joppot

コピペで絶対動く。説明を妥協しない

プログラミング

ruby on railsのckeditorをdeviseを用いて複数人で投稿できるようにする

投稿日:

Pocket

ckdevisesumb

概要

みなさんこんにちはcandleです。今回はckeditorの複数人投稿機能をdeviseを用いてやってみたいと思います。ckeditorを使うと分かると思うのですが、誰でも画像のアップロードや削除などができます。ただ、それだと複数人がckeditorを使って何かを登録する時に事故がおこりかねません。そこで今回はdeviseとckeditorとscaffoldを使って簡単にckeditorを複数にで使う方法を紹介します。


前提

deviseの導入がされている
deviseを導入しておいてください。

SPONSORED LINK


今回使うgem

今回使うgemは下のようになっています。twitterbootstrap gemはデザインで使うだけなので本番環境では使わなくてもよいです。twitterbootstrap gemを入れるデザインがbootstrapに上書きされたりするので注意してください。

gem 'twitter-bootstrap-rails', github: 'seyhunak/twitter-bootstrap-rails', branch: 'bootstrap3'
gem 'ckeditor'
gem 'carrierwave'
gem 'rmagick'
gem 'mini_magick'
gem 'devise'

インストールしておいてください。

bundle install


ckeditorで使うscaffoldを作る

scaffoldなのですが、twitterbootstrap gemを使用したscaffoldを作ります。この方がデザインの見栄えが良くなります。
scaffoldの名前はreportとします。下のコマンドでscaffoldを作ります。

rails g scaffold Report title:string author:string description:text

reportcommand

scaffoldで必要なファイルが作成されます。

作成されたマイグレーションファイルをデータベースに反映させます。

rake db:migrate

データベースが用意されたので、bootstrapのスタイルを適応します。

rails g bootstrap:layout application
rails g bootstrap:themed Reports

これを実行すると、テーマが自動的に書き込まれます。
実行すると分かる様に、すでにファイルが存在するので、コンフリクト(衝突)が起きてしまいます。上書きを許可しましょう。質問されたら「y」と答えれば良いです。

scaffoldが完成しました。

application layoutを編集する

これは別にやらなくても良いのですが、twitterbootstrap gemとdeviseを使っている場合はやっておくと便利です。railsプロジェクトのapp/views/layouts/application.html.erbを開きます。

メニューバーのul liの所に下のコードを加えます。

<% if user_signed_in? %>
  <li><a href="#" class="navbar-link">Logged in as <strong><%= current_user.email %></strong></a></li>
  <li> <%= link_to 'Edit profile', edit_user_registration_path, :class => 'navbar-link' %></li>
  <li><%= link_to "Logout", destroy_user_session_path, method: :delete, :class => 'navbar-link'  %></li>
<% else %>
  <li><%= link_to "Sign up", new_user_registration_path, :class => 'navbar-link'  %></li>
  <li><%= link_to "Login", new_user_session_path, :class => 'navbar-link'  %></li>
<% end %>

adddevisemenue

すると、twitterbootstrapを使っている場合は下の様にdeviseのログインに関するメニューが増えます。

applicationheadermenu


deviseで認証ユーザーを作成する

ckeditorでdeviseユーザーのテストするためには最低でも2人のアカウントが必要です。
二人前先に作っておきます。
deviseの画面のsign up を押します。

usersignup

emailは適当にやって、ユーザーを作ります。

createaliceuser

今回はaliceとbobを作りました。

ユーザーが出来ました。


deviseでログインしていないユーザーを除く

reportsコントロールにdeviseの認証機能を追加して、deviseでログインしたユーザーのみアクセスできるようにします。
app/controllers/reports_controller.rbを開きます。一番上に下記のコードを加えましょう。

before_action :authenticate_user!

authreports

これでckeditorをいじれる人はdevise認証をした人のみになります。


ckeditorをセットアップする

ではckeditorを使えるようにしましょう。

画像のアップロードができるように、下のコマンドでckeditorからcarrierwave経由でファイルがアップできる設定ファイルを作ります。

rails generate ckeditor:install --orm=active_record --backend=carrierwave

jsファイルを編集します。app/assets/javascripts/application.jsを開きます。
下の一文を加えましょう。

//= require ckeditor/init

保存します。

まだこれだけではckedtorが使えないので、ソースコードを編集して使えるようにします。app/views/reports/_form.html.erbを開きます。

始めに、authorの項目を削除します。authorのところは自分で入力するのではなくて、deviseの値をコントロール側で入れるので、viewでは入力させません。

<div class="form-group">
  <%= f.label :author, :class => 'control-label' %>
  <div class="controls">
    <%= f.text_field :author, :class => 'form-control' %>
  </div>
</div>

deleteauthorform

次に、descriptionの項目のf.text_fieldをf.cktext_areaに変更します。

<div class="form-group">
  <%= f.label :description, :class => 'control-label' %>
  <div class="controls">
    <%= f.cktext_area :description, :class => 'form-control' %>
  </div>
</div>

保存しましょう。

これで、newのアクションにブラウザから移動すると、下のようにckeditorが表示されるようになります。

newactionwithck


createアクションを変えます

authorカラムに入れるのは今はdeviseのemailの値にします。

下の一文をcreateアクションに加えます。

@report.author=current_user.email

repauthor

こうすることで、authorカラムにdeviseのemailの値が入ります。
試しに、ckeditorのフォームから新しく投稿してみましょう。

saikonoomoide

うまくいっていますね。


自分の作成した投稿のみ編集、削除できるようにする

aliceが作成した投稿をbobが削除したり、編集したりできてしまうと問題なので、編集と削除は自分が作成したものだけにしてみます。

まずはviewからapp/views/reports/index.html.erbを開きます。

actionのところを下の様にします。if文でactionを囲むことでアクションボタンを消します

<% if report.author==current_user.email  %>
  <%= link_to t('.edit', :default => t("helpers.links.edit")),
                      edit_report_path(report), :class => 'btn btn-default btn-xs' %>
  <%= link_to t('.destroy', :default => t("helpers.links.destroy")),
                      report_path(report),
                      :method => :delete,
                      :data => { :confirm => t('.confirm', :default => t("helpers.links.confirm", :default => 'Are you sure?')) },
                      :class => 'btn btn-xs btn-danger' %>
<% end %>

nestwithif

これをブラウザみると、下のようにaliceはaliceの書いたものだけを編集可能になります。

managementmyreport

ただこのままだと、URLを直打ちすると編集や削除ができてしまうので、コントローラーで著者じゃないユーザーはリダイレクトさせましょう。
app/controllers/reports_controller.rbをひらいて、editとdeleteアクションの一番始めに、下のコードを加えましょう。

if @report.author != current_user.email
  redirect_to controller: 'reports', action: 'index'
end

editredirect

deleredicrect

これでckeditorの投稿に関する設定は完了しました。

ckeditorの画像の管理

ckeditorは画像がアップロードできるのですが、デフォルトの設定では誰でも画像を削除したり編集したりできてしまうので、ckeditorのコントローラーをオーバライドします。
deviseユーザーが各自、自分でアップロードした画像のみを閲覧、編集、削除できるようにしましょう。

まずは普通に画像をアップロードしてみましょう。
aliceが1.pngをbobが2.pngをアップロードしました。

下の画像をみても分かるように、bobの操作でもaliceの写真に対してアクションができてしまいます。

nonsecurity

オーバーライドします。
まずはフォルダを作ります。

cd app/controllers/
mkdir ckeditor
cd ckeditor

次にckeditorが使っているpictureのコントローラーを作ります。

touch pictures_controller.rb

このファイルに下のコードを書き込んで保存しましょう。

class Ckeditor::PicturesController < Ckeditor::ApplicationController
  
 before_action :authenticate_user!
  def index
    @pictures = Ckeditor.picture_adapter.find_all(ckeditor_pictures_scope).where(assetable_id: current_user.id)
    @pictures = Ckeditor::Paginatable.new(@pictures).page(params[:page])

    respond_with(@pictures, :layout => @pictures.first_page?)
  end

end

bobの方からサーバブラウズしてみると、bobの画像のみ見れます。

bobmanagementwindow
これで複数人でのckeditorの利用が可能になりました。

上のコードにもありますが、先頭に下のコードを書くことで、
before_action :authenticate_user!

デバイスでログインしている人しかアクセス出来ないようにもなっています。


まとめ

すこし、マニアックな記事になってしまい、コード量もrailsにしては割と多かったと思います。

スポンサードリンク

「為になったなぁ」と思ったら、シェアお願いします。

-プログラミング
-

執筆者:


comment

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

関連記事

Mysqlで今日以降の最も近い日付を取得する

概要 みなさんこんにちはcandleです。今回はmysqlで今日以降の最も近い日にちを取得する方法を紹介します。 ライブや、イベントなどで、今日から見て、最も近い日のデータを取得したみたいなことってあ …

Chart.js 2.0でy軸の最大値(scales max)と最小値を設定する

概要 みなさんこんにちはcandleです。今回はChart.js2.0でy軸の最大値、最小値を設定する方法を紹介します。 Chart.js 2.0では特に指定しないと自動的に、y軸の最大値を設定してく …

ruby on railsのgemのインストールで不要なファイルをインストールしない設定

概要 みなさんこんにちはcandleです。私の記事はどうしても先人のプログラマーがまとめた内容を追試しているような感じになっていますが、これも重要なことなので、忘れないためにもまとめておきます。 ru …

正規表現を極めるその2

概要 みなさんこんにちはcandleです。今回は前回に引き続き、正規表現を勉強していきましょう。   前提 unixを使用するので、多少、unixコマンドになれていること   サン …

MysqlのSELECT FROMの結果を美しく、見やすく表示する

概要 みなさんこんにちはcandleです。今回はmysqlのデータベースに関する簡単な記事です。 データベース系の言語は最近、様々出てきましたが、私は未だにMysqlくらいしか触っていません。 私はp …

  • English
  • 日本語

プロフィール


ベンチャー企業のCTOをやってます。大学時代にプログラミングを始め、javaから入門し、C++へて、PHPへと進み、会社ではRailsを使用。自動化が大好きなプログラマー

スポンサードリンク

アーカイブ