今週のアウトプットはrailsでコメント投稿サイトを作っていた最中に苦戦したアソシエーションに関して復習ついでに書いていきたいと思います。
関連づけ(アソシエーション)とは
ユーザーがコメント投稿するようなサイトを例に説明すると、
誰が投稿したコメントなのかをデータとして保存しておく必要があります。
まずmodelでuserとpostcommentのカラムに以下の表のようにカラムを作ります。
現在のテーブル設計だけでは、投稿したユーザのIDはわかっても、そのテーブル内のユーザ名まではわかりません。
そこで、ユーザ情報のモデルと、投稿情報のモデルとを関連付ける必要があります。
user_id(投稿したユーザを識別するID)と、id(投稿コメントを識別するID)が、該当します。
また、1人のユーザが複数の画像を投稿できます。
これをモデルで表現すると、Userモデルで表される1人のユーザに対して、複数個(N個)のPostcommentモデルを関連付けることができます。
User | PostComment |
---|---|
id | id |
name | comment |
user_id | |
password | |
1:Nの関係 | | |
これを、1対Nの関係と呼びます。 |
1:Nの関係性をモデルに実装する(アソシエーションの実行)
UserモデルにPostCommentモデルを関連付ける
まずは、Userモデルに対して、PostCommentモデルが1:Nになるよう関連付けます。
class User < ApplicationRecord
has_many :post_comment, dependent: :destroy
end
※dependent: :destroyは親(この場合はUser)が消滅した時は子(この場合はpost_comment)も消滅するという意味
PostCommentモデルにUserモデルを関連付ける
次に、PostCommentモデルに対して、Userモデルとの関係性を追加していきます。
class PostComment < ApplicationRecord
belongs_to :user
end
関連づけにより参照先(userモデル)から値を参照できます。
@post_comment.user.name
第3のモデルを追加する場合のアソシエーション
上記のmodelにコメント投稿機能以外に画像投稿機能を追加したい場合の関連づけとしてhas_many :throughを用いると便利でした。以下のようにmodelを追加します。
User | PostComment | PostImage| |
---|---|---|
id | id | id |
name | comment | image_name |
user_id | image_id(画像) | |
password | post_image_id | |
1: N : Mの関係 | |
User : PostComment = 1 : N
User : PostImage = L : M
PostComment : PostImage = 1 : M
であるのでmodelに関係性を追加していきます。
class User < ApplicationRecord
has_many :post_comment
has_many :post_image through: :post_comment
end
class PostComment < ApplicationRecord
belongs_to :user
belongs_to :post_image
end
class PostImage << ApplicationRecord
has_many :post_comment
has_many :user through: :post_comment
end
has_many thoroughを利用することでpost_commentから直接Userモデルにアクセスすることができます。