このブログ初の記事になります!
igaigaさんの Railsの練習帳を読んで得た知見をアウトプットしていきます。
結論
- 規約から外れた関連付けにおいて双方向関連付けを行う場合、
inverse_of
の設定が必要になる。
双方向関連付け
関連付けにおいて、規約から外れた名前を使う時には、双方向関連付けを自動認識してくれません。
例えば以下のような関連のコードにおいては、双方向関連付けを自動で認識してくれます。
class User < ApplicationRecord has_many :books end class Book < ApplicationRecord belongs_to :user end
しかし、以下のようなコードだと双方向関連付けが自動では認識されません。
class User < ApplicationRecord has_many :books end class Book < ApplicationRecord belongs_to :author, foreign_key: "user_id", class_name: "User" end
一見うまく動作しそうですよね 👀
確認してみましょう。
user = User.first book = user.books.first user.name #=> "hoge" book.author.name #=> "hoge" user.name = "fuga" user.name #=> "fuga" book.author.name #=> "hoge"
このように、user.name
と book.author.name
の実行結果が違います。
これが 規約から外れ、双方向関連付けが自動で認識されなかった ということです。
では一体どのように解決したらいいのでしょうか。
inverse_of
を使う
手動で双方向関連付けを設定する必要があるのですが、これは inverse_of
を両者に設定することで解決できます。
(ちなみに inverse
は「逆」という意味だそうです。)
実際に使い方を見てみましょう。
class User < ApplicationRecord has_many :books, inverse_of: :author #inverse_of に続けて関連名を記述する end class Book < ApplicationRecord belongs_to :author, foreign_key: "user_id", class_name: "User", inverse_of: :books end
これで双方向関連付けを設定することができました!
双方向関連付けを行うと、
- 関連付けに起因するバグ
- 余分なクエリ発行
を防ぐことにつながります。
まとめ
- 規約から外れた関連付けの場合に双方向関連付けを行うには、
inverse_of
をつける
参考資料
初めての記事で至らぬところも多々あると思いますが、これからもこのブログを通して学んだことのアウトプットをしていきたいと思います!
ご拝読ありがとうございました 💪