Recently, I’ve resolved one more problem concerning the presence validator and a belongs_to association. But it involves another thing: accepts_nested_attributes. Assume you have a nested form and the parent object doesn’t exist yet. You can have this issue, and here I will show you how to fix it.
Issue
Let’s say we have the following models and their relationships:
class Account
has_one :user
accepts_nested_attributes_for :user
end
class User
belongs_to :account
validates :account, :presence => true
endGo to rails console and check the validator out:
irb(main):001:0> params = {:account => {:user_attributes => {}}}
irb(main):002:0> a = Account.new(params[:account])
irb(main):003:0> a.valid? # => false
irb(main):004:0> a.errors.full_messages # => ["User account can't be blank"]So this is our challenge: we can’t save the account because the user can’t pass validation, as the account (the parent model) doesn’t exist yet! But removing the validator wouldn’t be the right solution. Do you agree with me?
Solution
The solution is very simple: just add one more option, :inverse_of, to has_one (or has_many, if that’s what you have). With this option, Rails won’t try to get the account from the database when the user is validated. The account will be retrieved from memory. If you aren’t familiar with this option, I strongly recommend reading the official Rails guide.
So change the account model and try it:
class Account
has_one :user, :inverse_of => :account
accepts_nested_attributes_for :user
endirb(main):001:0> params = {:account => {:user_attributes => {}}}
irb(main):002:0> a = Account.new(params[:account])
irb(main):003:0> a.valid? # => trueI hope this article was helpful for you.