はじめに
初めまして!
私はRUNTEQでRuby on Railsをメインに勉強しています。
今回は私が関連付け(アソシエーション)の学習の過程で見落としてしまったが故に、後に苦労したことについて記録しておこうと思い、本記事を執筆しています。
本題
早速ですが、今回お伝えしたいのは次のようなことになります。
関連付けの際、has_manyやbelongs_toで指定したものはインスタンスメソッドとして使える。
例えば、一人のユーザーが複数のポストを投稿できるようにするという状況を仮定します。モデルにはUserとPostがあり、両者を関連付けします。関連付けには色々と手続きが必要ですが、その中でmodelsディレクトリには次のように書くでしょう。
has_many :posts, dependent: :destroy
# dependent: :destroyは本記事では重要ではありません。
belongs_to :user
このとき、posts
, user
はそれぞれインスタンスメソッドとして使えるということが今回伝えたいことです。もう少し厳密に言うと、ここではposts
はUserクラスのインスタンスに対して使うことができるインスタンスメソッドで、user
はPostクラスのインスタンスに対して使うことのできるインスタンスメソッドです。
インスタンスメソッドについてはこちらを参照
https://qiita.com/moshi1121/items/c74d350bab32113d4f3d
インスタンスメソッドとして使えるとはどういうことか
例えば、idが1のユーザーが投稿したポストを取得したいとき、通常はこのように書くでしょう。
@user = User.find(1) # idが1のユーザーを取得
@posts = Post.where(user_id: @user.id) # idが1のユーザーのポストを全て取得
上記のことは、posts
をインスタンスメソッドとして定義しているときは次のように書くことができます。
@user = User.find(1) # idが1のユーザーを取得
@posts = @user.posts # @userに結びついたポストを全て取得
同様に、インスタンスメソッドとして定義されたuser
を使うと、ポストを投稿したユーザーの情報を取得することができます。
@post = Post.find(1) # idが1のポストを取得
@user = @post.user # @postに結びついたユーザー情報を取得
これらインスタンスメソッドはさまざまな活用方法があるので、ぜひ試してみてください。
注意点
Railsガイドでは次のように注意がされています。
belongs_to関連付けで指定するモデル名は必ず「単数形」にしなければなりません。
has_many関連付けを宣言する場合、相手のモデル名は「複数形」で指定する必要があります。
つまり、先ほどの例で言うと
has_many :posts
belongs_to :user
これは認められても
has_many :post
belongs_to :users
これは認められないということになります。
現状、has_manyに関しては単数形でもそれなりに通ってしまいます。
また、モデル名に関係のない適当な名前を指定しても機能しないので、お気をつけください。
終わりに
今回は簡単にhas_manyとbelongs_toのみを取り上げましたが、同様のことはRailsがサポートする6つの関連付け全てに当てはまることです。
・belongs_to
・has_one
・has_many
・has_many :through
・has_one :through
・has_and_belongs_to_many