Edit: Clarifications added
Given the following two classes
class Foo < ActiveRecord::Base
belongs_to :bar
end
class Bar < ActiveRecord::Base
end
When I change a bar on a foo, I would like a way to see that the foo instance has changed:
foo = Foo.find(x)
foo.bar # returns #<Bar id:1>
foo.bar = Bar.new
foo.changed? # returns false
foo.changes # returns an empty hash
I don't want to set bar_id as dirty (because it hasn't changed) It would be nice to have the following:
foo.changed? # returns true
foo.changes # returns {:bar => [#<Bar id: 1>, nil]}
Is there a clever way to hack this into Rails? Is there a reason this is not part of Rails?
Due to changes to
@changed_attributes
in Rails 5.1, I had to resort to using a virtual attribute (attr_accessor) to indicate the changed association after checks. This might be better in the long run compared to messing with Rails internals related toActiveRecord::Dirty
What version of Rails are you using? When I tested it, it does report true.
Anyway, I am not sure if an after assign callback is available for belongs_to yet. There was a ticket for this https://github.com/rails/rails/issues/586
If not, you can just override the assign method (I haven't tried this before, but I think it will work :) so please let me know)
Update: Just read your question again, and I am not even sure if I understood all of it. You want it to still report true if it hasn't changed? Even when assigning the same object again right? in which case you can remove the
unless bar_id == b.id
partI faced the same problem today and after running through the rails-source i found a workaround that should do what you had in mind, if i got your question the right way.
Transferred to your example the code should look like that:
This way you can call .changed? and .changes on objects of the Foo-class.
hope this helps even if the answer comes a bit late :)
kind regards christian
btw. sorry for the poor english. i am working on that as much as on my ruby-skills ;)