Rails skips validations when manually saving child instances, while autosave has been turned off.
I have got the following simplified model of houses with rooms.
class House < ActiveRecord::Base
has_many :rooms, inverse_of: :house, autosave: false
class Room < ActiveRecord::Base
belongs_to :house, inverse_of: :rooms
validates :house, presence: true
I validate, that every room has to have a house.
Now I create a house instance and an associated room and save the house instance.
house = House.new
room = house.rooms.new
Since I use inverse_of, my room should be up to date and I check the house and try to save the room.
=> #<House id: 13, name: nil, created_at: "2014-02-24 19:28:59", updated_at: "2014-02-24 19:28:59">
Everythings works, validation does not complain, but if I check the created room it has "house_id = nil".
=> #<Room id: 30, name: nil, house_id: nil, created_at: "2014-02-24 19:34:22", updated_at: "2014-02-24 19:34:22">
Saving the house first and then calling house.rooms.new however works. But its not obvious to me that my way of doing it is prohibited, since the house seems to be linked correctly and validations do not fail. The documentation does not give any example about autosave => false, so I am clueless whether this is a bug or if it's simply prohibited to call rooms.new on a new record, when autosave is false ?
When the house is not saved house.rooms.new creates a room, which ends up with house_id nil. Apparently autosave: false on house means that the room.house_id will not get updated once house is saved. I'm guessing validation checks for room.house being nil and probably doesn't care about room.house_id being nil. Reloading the saved room will update room.house to nil.
I am starting to understand the reasons for this behavior. Its a rare interplay of associations and autosave while using inverse_of.
If I wouldn't use inverse_of, the house wouldn't get saved, because of "invalid rooms" (even with autosave => false). As well room.house would be nil (without inverse_of)
There is another option has_many , :validate => false . If you use that in combination with autosave: false (not using inverse_of). Then your're able to save the house, but room.house is still nil.
Most of the time I dont want to save parent and children in different transactions, but I came across this issue, when I wanted to do it manually.
So far, my advice, be careful with inverse_of and autosave and presence validations for associations. It might lead to malicious records.
I would highly appreciate further thoughts!
This issue has been automatically marked as stale because it has not been commented on for at least
The resources of the Rails team are limited, and so we are asking for your help.
If you can still reproduce this error on the 4-1-stable, 4-0-stable branches or on master,
please reply with all of the information you have about it in order to keep the issue open.
Thank you for all your contributions.
This issue has been automatically closed because of inactivity.