Ruby on RailsでユーザIDと入力データの関連付けをする
前回の記事では、Deviseを利用して、ユーザ認証を実装しました。今回はその続きでログインユーザ自身が入力したデータのみ参照・追加・更新が出来るようにデータのアクセスコントロールをしていこうを思います。
実装仕様
1. ログインしたユーザ自身が投稿した内容しか表示されない。
2. もちろんですが、ログインしないと投稿が出来ない。
上記のイメージで作っていきたいと思います。
利用環境
今回の利用したRails環境は以下のとおりです。
OS: Windows XP (そろそろ変えたい…)
Ruby: Ruby 2.0.0p247
Rails: Rails 4.0.0
* 前回の記事内容のDevise実装が出来ている事とします。
実施内容
まず、scaffoldを利用して、postsモデルとビューを作成とdb:migrate
$ rails generate scaffold post content:string
$ bundle exec rake db:migrate
postsモデルにuser_idを追加する。
$ rails generate migration add_user_id_to_posts user_id
user_idの型をIntegerに変更
ファイル:db/migrate/(日付時間)_add_user_id_to_posts.rb
以下の記述に変更
add_column :posts, :user_id, :integer
db:migrateを実施し、DBに変更を反映する。
$ bundle exec rake db:migrate
モデル間の関係を記載する。
1. postsがusersに所属している。かつpostのuser_idは必須
ファイル:app/models/post.rb
以下の記述を追加
belongs_to :user
validates :user_id, presence: true
2. usersとpostsは1対多になる。
ファイル:app/models/user.rb
以下の記述を追加
belongs_to :user
コントローラを修正する。自分が投稿した内容のみを表示するようにする。
current_userというDeviseのヘルパーを利用すると、現在ログインしているuserオブジェクトを返してくれるみたいなので、それを利用する。基本現状Postとなっている箇所をcurrent_user.postsに変更する。
ファイル:app/controllers/posts_controller.rb
まずは、以下の記述を追加
before_filter :authenticate_user!
修正1:自分で投稿した内容のみ表示する。(index)
・修正前
def index
@posts = Post.all
end
・修正後
def index
@posts = current_user.posts.all
end
修正2:自分で投稿した内容のみ表示する。(show)
・修正前
def set_post
@post = Post.find(params[:id])
end
・修正後
def set_post
@post = current_user.posts.find(params[:id])
end
修正3:セキュリティの設定をいじって、user_idデータも許すようにする。
・修正前
def post_params
params.require(:post).permit(:content)
end
・修正後
def post_params
params.require(:post).permit(:content, :user_id)
end
ビューを修正する。_form.html.erb(newとeditで利用している)のviewを修正。内容は、user_idをhiddenで追加して、Submitするようにする。
ファイル:app/views/posts/_form.html.erb
・修正前
<div class="field">
<%= f.label :content %><br>
<%= f.text_field :content %>
</div>
・修正後
<div class="field">
<%= f.label :content %><br>
<%= f.text_field :content %>
<%= f.hidden_field :user_id, value: current_user.id %>
</div>
これで、ログインしたユーザの投稿内容のみ表示できるようになりました。今日の所は疲れたので、ここまでとします。