This project is archived and is in readonly mode.
unchanged attribute is changed [ActiveModel]
-
eagle.anton (at gmail)
- Tag set to rails3 active_model dirty
-
lakshmanan
works for me ! It(Ticket) seems invalid ..
I tried this in console as well.
-
lakshmanan
- Tag changed from rails3 active_model dirty to rails3 active_model dirty, invalid
-
Rohit Arondekar
- State changed from new to open
- Assigned user set to josh
- Tag changed from rails3 active_model dirty, invalid to rails 3, activemodel, dirty
- Importance changed from to Low
Confirmed that the provided test fails on Rails master.
Can you try writing a patch to fix this?
-
Tore Darell
Maybe I'm missing something, but I don't think the test from the diff should pass, using the example implementation from Dirty. The
attribute_will_change!method says to Dirty that it will change, so it adds the attribute name and value to @changed_attributes@, which is used byattribute_changed?to determine if it's been changed or not, usingchanged_attributes.include?(attr).It seems to me it's up to the implementer to decide when an attribute changes or not, and in the example class a change is recorded every time
name=is called. Maybe the examples were copied from when this was part of ActiveRecord, where the test would pass AFAIK. -
Rohit Arondekar
I think Tore is right. By calling name_will_change! in Person#name=, it's already decided that the attribute has changed.
If this is the desired behavior, which I think is a good idea, then the API docs need to be fixed.
-
Rohit Arondekar
Calling attr_will_change! accordingly is fine but I don't think there is a method that marks a attribute or the entire object as clean.
So how do I tell AMo that the object is now clean in my save method? That is, all the pending changes have been applied so that model.changed? #=> false. I'm guessing it can be done by changing the @changed_attributes map manually.
Would be useful to do will_be_clean! and maybe even attr_will_be_clean!.
-
Tore Darell
It looks like ARec does this.. From http://github.com/rails/rails/blob/master/activerecord/lib/active_record/attribute_methods/dirty.rb#L23:
def save(*) #:nodoc: if status = super @previously_changed = changes @changed_attributes.clear end status end -
Rohit Arondekar
The API docs: http://edgeapi.rubyonrails.org/classes/ActiveModel/Dirty.html are pretty misleading. The given examples don't work on the example class given. And they won't work unless the user adds more code. 'Save' and 'Assigning the same value leaves the attribute unchanged' don't work for ex.
Should the example Person class be beefed up to support the examples? Or should the non-working examples be removed?
Also how about providing convenience methods like clear_changes! for @changed_attributes.clear and archive_changes! for @previously_changed = changes? Maybe even a archive_and_clear_changes! for doing both in one shot.
-
Tore Darell
Attaching a patch which fixes the docs and adds a few more tests.
-
Tore Darell
Left out the original issue from the patch, but this should include it..
-
Rohit Arondekar
- Assigned user changed from josh to José Valim
- Milestone cleared.
Thanks Tore! :)
Just one very small nitpick though — The test "setting name will result in change" could be named as "setting attribute will result in change".
-
José Valim
Patch no longer applies, could you please rebase? Thanks!
-
José Valim
- Milestone set to 3.x
-
Tore Darell
Changed.
-
Rohit Arondekar
Jose, any reason why this is not going into 3.0? It's not changing the API, only fixing the docs and adding some more tests.
-
Repository
- State changed from open to resolved
(from [2c8a4a53a8c38a43a62342b9d46014242e781d18]) Remove or fix non-working examples and add a few tests to Dirty [#5185 state:resolved]
Signed-off-by: José Valim jose.valim@gmail.com
http://github.com/rails/rails/commit/2c8a4a53a8c38a43a62342b9d46014...
