積々RUNMIZZO

日々積み重ね

【Ruby on Rails】投稿したユーザーのみ編集&削除を表示させる実装奮闘記

Railsに対する基本理解が深まった経験の記録。
(途中起きたエラー内容および対応は割愛)

実現したいこと


  • 投稿したユーザーのみに編集&削除を表示させる
    ※view表示にフォーカス
    (他ユーザーからの編集&削除権限の制限実装については割愛)

本実装までの考え方


  1. if文を使ってviewの表示を使い分る
  2. 既存テーブルにカラムを追加
  3. Sorceryで使えるメソッド
  4. モデル同士の紐付け
  5. 投稿時に投稿者のuser_idを追加

開発環境


前提


  • Sorceryを使ったユーザー新規登録&ログイン&ログイン機能(user)
  • 新規投稿&編集&削除機能(post)

以上実装済

詳細


1. if文を使ってviewの表示を使い分ける

はじめに色々ググっていると最終的に以下のコードが通れば上手く表示されるんかな〜という考えにたどり着く。

<% @posts.each do |post| %>
  <tr>
・・・
    <% if post.user_id == current_user.id %>
      <td><%= link_to 'Edit', edit_post_path(post) %></td>
      <td><%= link_to 'Destroy', post, method: :delete, data: { confirm: 'Are you sure?' } %></td>
    <% end %>
  </tr>
<% end %>
・・・
2. 既存テーブルにカラムを追加

post.user_idcurrent_user.idの数字が一致すれば、、
でもpostsテーブルにuser_idカラムなんてあったっけ?

db/migrate/schema.rb

・・・
create_table "posts", force: :cascade do |t|
  t.string "title"
  t.text "content"
  t.datetime "created_at", null: false
  t.datetime "updated_at", null: false
end
・・・

無いッスね。
つまり追加しないといけないので、、
$ rails g migration AddUserIdToPosts user_id:string
(既存テーブルのカラム追加してくれる優しい奴)
をコマンド実行して自動生成されたdb/migrate/XXXXXXXXXXXXXX_add_user_id_to_posts.rb

・・・
def change
  add_column :posts, :user_id, :integer
end
・・・

を追記して$ rails db:migrate

db/migrate/schema.rb(変更後)

・・・
create_table "posts", force: :cascade do |t|
  t.string "title"
  t.text "content"
  t.datetime "created_at", null: false
  t.datetime "updated_at", null: false
  t.integer "user_id"
end
・・・

このt.integer "user_id"が増えたことでカラムの追加が完了!

3. Sorceryで使えるメソッド

current_user.idというのはSorceryに元々備わっているメソッドで ログイン中のユーザーIDを拾ってくれる便利な奴とのこと(有り難い!)

4. モデル同士の紐付け

ユーザー1人に対して投稿は複数存在するから「1対多」の関係にあるため
app/models/post.rb

class Post < ApplicationRecord
  belongs_to :user
end

app/models/user.rb

class User < ApplicationRecord
  authenticates_with_sorcery!
・・・
  has_many :posts, dependent: :destroy
end

をそれぞれ追記すると上手く紐付いてくれました◎
dependent: :destroyはuserを削除した時紐付いたpostsも一緒に消しまっせってことらしい)

5. 投稿時に投稿者のuser_idを追加

最後に、
app/controllers/posts_controllers.rb
で新規投稿時にログインユーザーのIDがuser_idに追加されるように修正。
(変更前)

・・・
def create
    @post = Post.new(post_params)
・・・

(変更後)

・・・
def create
    @post = current_user.posts.build(post_params)
・・・

user.rbに「has_many :posts」があると「Userインスタンス.posts.build」というメソッドが使えるらしい◎

以上で実装完了!
大作になってしまった。。

参考記事