教材の内容に関係のない質問や教材とは異なる環境・バージョンで進めている場合のエラーなど、教材に関係しない質問は推奨していないため回答できない場合がございます。
その場合、teratailなどの外部サイトを利用して質問することをおすすめします。教材の誤字脱字や追記・改善の要望は「文章の間違いや改善点の指摘」からお願いします。
この章ではコメント機能を開発していきます。
本パートではCommentモデルを作成し、アソシエーションの設定まで行います。
このパートは「5-1 モデルの作成」とほとんど同じような流れで進めていきます。
コメント機能を作成するにはデータベースにコメントの情報を保存する処理が必要になります。
なのでまずデータベースのやり取りを行うモデルを作成していきます。
コメントに必要な情報は以下の3つになります。
Copied!- コメントの内容
- どの投稿にコメントをしたか投稿の情報
- 誰がコメントしたかユーザーの情報
この3つの情報を格納するためにcommentsテーブルを作成します。
commentsテーブルの構成は以下のようになります。
references型で保存すると、post_id
とuser_id
を外部キーとして明示的に指定できます。
では、Commentモデルを作成するに以下のコマンドを実行してください。
Copied!$ rails g model Comment
上記のコマンドで新しくマイグレーションファイルも作成されます。
早速その作成されたマイグレーションファイルを以下のように編集してください。
Copied!db
└── migrate
└── xxxxxx_create_comments.rb
db/migrate/xxxxxx_create_comments.rb1234567891011121314 Copied!class CreateComments < ActiveRecord::Migration[6.0]
def change
create_table :comments do |t|
# ==========ここから追加する==========
t.text :comment, null: false
t.references :post, foreign_key: true, null: false
t.references :user, foreign_key: true, null: false
# ==========ここまで追加する==========
t.timestamps
end
end
end
foreign_key: true
は外部キーとして使用するということを示しています。
では、マイグレーションファイルを実行してcommentsテーブルを作成します。
Copied!$ rails db:migrate
上記のコマンドを実行すると下記のような実行結果が表示されます。
Copied!== 20190312004408 CreateComments: migrating ===================================
-- create_table(:comments)
-> 0.0021s
== 20190312004408 CreateComments: migrated (0.0023s) ==========================
モデルを作成したらアソシエーションの設定を行います。
アソシエーションとは、2つのモデル同士のつながりを指します。モデルとモデルの間には関連付けを行う必要があります。
参考)Active Record の関連付け (アソシエーション)
まずUserモデルとCommentモデルのアソシエーションを設定していきます。
上記2つのモデルの関係性は以下のようになります。
Copied!- ユーザーは複数のコメントをすることができる
- コメントAに関して、コメントAをしたユーザーは一人しかいない
つまり、UserモデルとCommentモデルは「1対多」の関係になります。
では、app/models/user.rb
に以下のコードを追加してください。
Copied!app
└── models
└── user.rb
app/models/user.rb123456789 Copied!class User < ApplicationRecord
has_many :posts, dependent: :destroy
has_many :likes
# この行を追加する
has_many :comments
.
.
.
has_manyは、他のモデルとの間に「1対多」のつながりがあることを示します。(「1側」にhas_manyを追加します。)
has_manyが使用されている場合、「反対側」のモデルでは多くの場合belongs_to
が使われます。
次にapp/models/comment.rb
に以下のコードを追加してください。
Copied!app
└── models
└── comment.rb
app/models/comment.rb123456 Copied!class Comment < ApplicationRecord
# この行を追加する
belongs_to :user
end
これでUserモデルとCommentモデルのアソシエーション設定ができました。
同じ要領で今度はPostモデルとCommentモデルのアソシエーションを設定します。
上記2つのモデルの関係性は以下のようになります。
Copied!- 一つの投稿は複数のコメントを持つことができる
- コメントAに関して、コメントAに紐づく投稿は一つしかない
つまり、PostモデルとCommentモデルは「1対多」の関係になります。
では、app/models/post.rb
に以下のコードを追加してください。
Copied!app
└── models
└── post.rb
app/models/post.rb123456789101112131415 Copied!class Post < ApplicationRecord
belongs_to :user
has_many :photos, dependent: :destroy
has_many :likes, dependent: :destroy
# この行を追加する
has_many :comments, dependent: :destroy
accepts_nested_attributes_for :photos
def liked_by(current_user)
# user_idが一致するlikeを検索する
Like.find_by(user_id: current_user.id, post_id: id)
end
end
dependent: :destroy
をつけることで、オブジェクトが削除されるときに、関連付けられたオブジェクトのdestroyメソッドが実行されます。つまり今回で言うと、投稿が削除されたら、その投稿に紐づくコメントも削除します。
参考)Active Record の関連付け (アソシエーション) :dependent
次にapp/models/comment.rb
に以下のコードを追加してください。
Copied!app
└── models
└── comment.rb
app/models/comment.rb123456 Copied!class Comment < ApplicationRecord
belongs_to :user
# この行を追加する
belongs_to :post
end
以上で今回のパートは終了です。
お疲れさまでした。