LoginSignup
28
28

More than 5 years have passed since last update.

railsのキホンvol.9(投稿とユーザーの紐付け)

Last updated at Posted at 2019-03-19

投稿とユーザーの紐付け

まず、各投稿が誰がしたのかを判別するためにpostsテーブル(投稿系のテーブル)に、user_idというカラムをたす。

$ rails g migration add_user_id_to_posts

↑コマンドにより、マイグレーションファイルを作り、changeメソッドを書いて、データベースを更新する。

add_user_id_to_posts.rb
def change
  add_column :posts,:user_id,:integer
end
$ rails db:migrate

投稿したユーザーのidを保存

投稿を保存する際に、先ほど追加したuser_idカラムにも情報を入れる。
@current_user.idは投稿しようとしているユーザーのidを表すので、

posts_controller.rb
def create
    @post = Post.new(
      content: params[:content],
      #今回追加する操作
      user_id: @current_user.id
    )
end

とすればいい。

投稿詳細ページでユーザー画像とユーザー名を表示する

投稿とユーザーの紐付けは完了したから、次はその紐付けを使ってユーザー情報を表示する。

posts_controller.rb
def show
    @post = Post.find_by(id: params[:id])
    @user = User.find_by(id: @post.user_id)
end
show.html.erb
<img src="<%= "/user_images/#{@user.image_name}" %>">
<%= link_to(@user.name,"users/#{@user.id}") %>

このようにすれば表示できる。

インスタンスメソッド

投稿に紐づくユーザーの情報はよく使うのでインスタンスメソッドとしておく。
railsではモデル内にインスタンスを定義することができるので
今回はPostモデル内に定義しておく。

models/post.rb
def user
  #インスタンスメソッドないで、selfはインスタンス自身を表す
  return User.find_by(id: self.user_id)
end

showアクション内の@userを削除し、ビューファイルの方は@userをuserとしておく。

投稿一覧でユーザーと投稿を紐付ける(whereメソッド)

投稿一覧のようなユーザーに紐づく投稿が複数ある場合、find_byメソッドは一件しか取得できないので、whereメソッドを用いる。

投稿を複数取得する処理もよく使うのでモデル内でインスタンスを定義しておく。

models/user.rb
def posts
  return Post.where(user_id: self.id)
end

ユーザー詳細ページにユーザーの投稿を表示する。

定義したpostsインスタンスを使って、投稿を取得し、ユーザー詳細ページに表示する。

users/show.html.erb
  <% @user.posts.each do |post| %>
    #画像、ユーザネーム、投稿をそれぞれ表示
  <% end %>
end

投稿者のみに編集・削除リンクを表示させる。

ログインしているユーザーが、その投稿の作成者である場合は、編集・削除をできるようにする。

posts/show.html.erb
<% if @post.user_id == @current_user.id %>
  <%= link_to("編集","users/#{@post.id}/edit") %>
  <%= link_to("削除","users/#{@post.id}/destroy",{method:"post"}) %>
<% end %>

このままだと、直接アクセスした場合は編集、削除ができてしまうから、投稿に紐づくユーザーとログインしているユーザーが違う場合は編集・削除をできないようにする。

postsコントローラ内に ensure_correct_user メソッドを作り、 before_action で対応するアクションに対してメソッドを適用させる。

posts_controller.rb
before_action :ensure_correct_user,{only: [:edit,:update,:destroy]}
#...
def ensure_correct_user
  @post = Post.find_by(id: params[:id])
  if @post.user_id != @current_user.id
  flash[:notice] = "権限がありません"
  redirect_to("/posts/index")
end

続き
https://qiita.com/jonnyjonnyj1397/items/e0266dadbd63d9bdec10

28
28
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
28
28