LoginSignup
13
6

has_many, belongs_toでインスタンスメソッドを定義している件について

Last updated at Posted at 2023-10-01

はじめに

初めまして! 
私はRUNTEQでRuby on Railsをメインに勉強しています。
今回は私が関連付け(アソシエーション)の学習の過程で見落としてしまったが故に、後に苦労したことについて記録しておこうと思い、本記事を執筆しています。

本題

早速ですが、今回お伝えしたいのは次のようなことになります。

関連付けの際、has_manyやbelongs_toで指定したものはインスタンスメソッドとして使える。

例えば、一人のユーザーが複数のポストを投稿できるようにするという状況を仮定します。モデルにはUserとPostがあり、両者を関連付けします。関連付けには色々と手続きが必要ですが、その中でmodelsディレクトリには次のように書くでしょう。

app/models/user.rb
has_many :posts, dependent: :destroy
# dependent: :destroyは本記事では重要ではありません。
app/models/post.rb
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関連付けを宣言する場合、相手のモデル名は「複数形」で指定する必要があります。

つまり、先ほどの例で言うと

app/models/user.rb
has_many :posts
app/models/post.rb
belongs_to :user

これは認められても

app/models/user.rb
has_many :post
app/models/post.rb
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

13
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
6