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とは、アソシエーションによって紐づけられた外部キーの値が存在していなくても、データベースに保存することができるオプションです。
これで関連付けが完了。