Lighthouse has a new layout. Prefer the old one? Return to the old layout, and switch back any time from the link at the top of each page.

This project is archived and is in readonly mode.

unchanged attribute is changed [ActiveModel]

#5185

ActiveModel::Dirty has the example:

# Assigning the same value leaves the attribute unchanged:
#   person.name = 'Bill'
#   person.name_changed?  # => false
#   person.name_change    # => nil

It isn't working.

Test in attachment failes.

Reported by eagle.anton (at gmail) · July 23rd, 2010 @ 01:37 PM

State: resolved
Milestone: 3.x
Assigned to: José Valim José Valim
Importance: Low

Activity

  1. eagle.anton (at gmail)
    eagle.anton (at gmail)
    • Tag set to rails3 active_model dirty

    July 23rd, 2010 @ 02:25 PM

  2. lakshmanan
    lakshmanan

    works for me ! It(Ticket) seems invalid ..

    I tried this in console as well.

    July 24th, 2010 @ 01:32 PM

  3. lakshmanan
    lakshmanan
    • Tag changed from rails3 active_model dirty to rails3 active_model dirty, invalid

    July 24th, 2010 @ 02:53 PM

  4. Rohit Arondekar
    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?

    July 25th, 2010 @ 02:39 AM

  5. Tore Darell
    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 by attribute_changed? to determine if it's been changed or not, using changed_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.

    July 25th, 2010 @ 12:53 PM

  6. Rohit Arondekar
    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.

    July 25th, 2010 @ 01:07 PM

  7. Rohit Arondekar
    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!.

    July 25th, 2010 @ 01:56 PM

  8. Tore Darell
    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
    

    July 25th, 2010 @ 02:16 PM

  9. Rohit Arondekar
    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.

    July 26th, 2010 @ 07:59 AM

  10. Tore Darell
    Tore Darell

    Attaching a patch which fixes the docs and adds a few more tests.

    July 26th, 2010 @ 03:11 PM

  11. Tore Darell
    Tore Darell

    Left out the original issue from the patch, but this should include it..

    July 26th, 2010 @ 03:48 PM

  12. Rohit Arondekar
    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".

    July 26th, 2010 @ 04:19 PM

  13. José Valim
    José Valim

    Patch no longer applies, could you please rebase? Thanks!

    August 2nd, 2010 @ 04:05 PM

  14. José Valim
  15. Tore Darell
  16. Rohit Arondekar
    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.

    August 3rd, 2010 @ 08:12 AM

  17. Repository
    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...

    August 3rd, 2010 @ 09:53 AM

  18. Ryan Bigg
    Ryan Bigg
    • Tag cleared.

    Automatic cleanup of spam.

    November 8th, 2010 @ 01:51 AM