Rails6でユーザーと投稿を結びつける方法

ユーザーと投稿を結びつける方法

ユーザーの投稿一覧を見れるようになるまで実装します。

投稿機能はscaffoldではなく、独自に作りました。(ほぼ内容はscaffoldと同じですが、、、)

バージョンと仕様

  • ruby 2.6.6p146 (2020-03-31 revision 67876) [x86_64-darwin19]
  • Rails 6.1.0
  • devise (4.7.3)
  • gem 3.0.3

postsテーブルに投稿とユーザーを結ぶためのカラムを追加

rails g migration AddUserIdToPosts user_id:integer
rails db:migrate

current_userメソッド( deviseのメソッド )

ログイン中のユーザー情報を取得できる。

ユーザーが送信する情報とこの「ユーザー情報」を結合する為、posts_controller.rbに下記を使用

merge メソッドです。

private
    # 仮に悪意のあるリクエスト(指定した以外のデータを送ってくる等)を受けた際に、.permitメソッドで許可していない項目については変更されず、データの扱いがより安全になります。
    def post_params
        params.require(:post).permit(:title, :content).merge(user_id: current_user.id)
    end

データベースに必要情報(user_id)が追加されるか動作確認をしてみます。

記事を投稿して、railsコンソールで確認しましょう。

$ rails c
Running via Spring preloader in process 26950
Loading development environment (Rails 6.1.0)
irb(main):001:0> Post.find(3)
   (1.4ms)  SELECT sqlite_version(*)
  Post Load (1.0ms)  SELECT "posts".* FROM "posts" WHERE "posts"."id" = ? LIMIT ?  [["id", 3], ["LIMIT", 1]]
=> #<Post id: 3, title: "タイトル3/jpkr/inves", content: "### 解決したいこと\r\nここに解決したい内容を記載してください。\r\n例)\r\nRuby on Rai...", created_at: "2020-12-21 07:37:48.364703000 +0000", updated_at: "2020-12-21 16:55:50.964213000 +0000", public_uid: "47844d099ff44291217b", user_id: 2>
irb(main):002:0> 

user_idカラムに現在ログイン中のユーザーidが追加されました。

アソシエーション(テーブル同士の関連付け)

テーブル同士の関連付けをします。

has_many メソッド 

そのモデルから見て、もう一つのモデルには関連データが複数あること。

例)ユーザーAのデータはもう一つのテーブルに複数ある。

app/models/user.rbに下記追加。

has_many :posts, dependent: :destroy

belongs_to メソッド

一つの投稿データは一人のユーザーが持つデータと言う関係を表す。

app/models/post.rbに下記追加。

belongs_to :users, optional: true

optional: trueは、外部キーの値が空白(null)であれば、バリデーションで弾かれてしまうのを防ぎます。(これが無いと投稿するときに「Userが入力されていません」みたいなバリデーションエラーが出る)

外部キーがないと弾かれてしまう挙動は、Rails5以降から導入されたらしい。

つまり、optional: trueとは、アソシエーションによって紐づけられた外部キーの値が存在していなくても、データベースに保存することができるオプションです。

これで関連付けが完了。

他にもこんな記事があります!