おさとの雑記帳

日々の学習のアウトプットに使っていきます!

Railsの練習帳を読んでみた

このブログ初の記事になります!

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.namebook.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 をつける

参考資料

初めての記事で至らぬところも多々あると思いますが、これからもこのブログを通して学んだことのアウトプットをしていきたいと思います!

ご拝読ありがとうございました 💪