Given the following definitions
Foo
has_many :bars, :dependent => :nullify, :autosave => false
Bar
validates_presense_of :foo
foo_id is not null # database constraint
I would like to re-associate a Bar object to a different Foo object. I need it all correctly done in memory so I can render everything in case after all work validation fails.
The problem is when I do something like
bar.foo.bars.delete(bar)
bar.foo = other_foo
other_foo.bars << bar
I get a failure that at bar.foo.bars.delete(bar) a sql update executes nulling out my bar’s foo_id property. Therefore sql constraint exception and failure. I instead need it to just work all in memory and fail validation if necessary.
Edit:
The thing is this is all in a transaction so I don’t care about db updates, I just don’t want them triggering database constraint issues, yet I want my constraints to be present and not allow a null value in the db for my Bar object. When my save executes, if it succeeds, I want my save to re-associate everything as appropriate. If it fails I want my memory model to be in the correctly updated (but not valid) state, this way I can render my page with the updated values and messages that the update failed.
Honestly my main goal is to have the following situation:
before:
foo1.bars => [bar1, bar2]
foo2.bars => [bar3]
after:
foo1.bars => [bar1]
foo2.bars => [bar3, bar2]
So my main goal is to solve this problem (in-memory full update of all appropriate objects), if it involves not dealing with re-associating like I already have, I’ll accept that too.
To remove an associated child (bar1) element from the parent’s (foo1) collection of bars you can use
This will remove bar1 from the foo1’s bars collection but bar1 will remain unchanged in the database because
delete_ifworks on the Enumerable on which the HasManyAssociation is built on.