webエンジニアの日常

RubyやPython, JSなど、IT関連の記事を書いています

inverse_ofってどういうときに使うの?

Rails Guide の説明では

「inverse_ofオプションを提供していて、これを使うと双方向の関連付けを明示的に宣言することができます。」

とありますが、正直言ってることがよく分からんという方、そして自分へのメモです。

例えば、次のようなモデルのとき

(注)あくまでも例なので、この設計がどうとかは置いといてください

class User < ApplicationRecord

  has_one :profile
  accepts_nested_attributes_for :profile, reject_if: :all_blank
end

class Profile< ApplicationRecord
  belongs_to :user
end

このモデルで、例えば、Profileの方に、Userのあるカラムが存在するときだけ発動したいバリデーションがあるとします

スポンサーリンク

class User < ApplicationRecord

  has_one :profile
  accepts_nested_attributes_for :profile, reject_if: :all_blank
end

class Profile< ApplicationRecord
  belongs_to :user

  validates :age, presence: true, if: ->(v){v.user.birthday.present?}
end

このとき、残念ながら今のままではv.userが見つからず、エラーになってしまいます

そこで、Userモデルの関連にinverse_ofオプションをつけます

class User < ApplicationRecord

  has_one :profile
  accepts_nested_attributes_for :profile, reject_if: :all_blank, inverse_of: 'user'
end

class Profile< ApplicationRecord
  belongs_to :user

  validates :age, presence: true, if: ->(v){v.user.birthday.present?}
end

これでまだ登録されていない場合でもバリデーションを発動させることが出来ます