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.

Dirty tracking doesn't catch in-place changes to field values

#391

It appears that the dirty field functionality can miss field changes if they're done without outright object re-assignment. For example, this code:

user = User.find_by_login 'francis'

user.login << '_the_king'

user.save

won't actually save the user record, because ActiveRecord isn't able to intercept String#<< . This code will also fail to save:

user = User.find_by_login 'francis'

user.login.replace 'francis_is_the_best'

user.save

for the same reason.

I suspect this is a duplicate of Andre Foeken's bug #360 Dirty tracking on serialized columns is broken.

It is possible, of course, to workaround in specific cases by doing things like

user.login_changed!

but that seems pretty broken IMHO. If my ORM layer isn't letting me fully use my object-oriented language without having to worry about silent failures that can take forever to track down, I'm not sure what the "O" is there for.

Maybe the solution would be to turn this off by default, communicate to Rails developers the tricky side-effects of this feature, and then give them the ability to selectively turn the feature on in specific models?

Reported by fhwang · June 11th, 2008 @ 06:29 PM

State: invalid
Milestone: none
Assigned to: Jeremy Kemper Jeremy Kemper
Importance: none

Activity

  1. Jeremy Kemper
    Jeremy Kemper
    • State changed from new to invalid
    • Assigned user set to Jeremy Kemper

    This is intentional and well-documented.

    The dirty plugin froze attributes, treating the database values as immutable. This is a big change, though, so when I merged with Rails I kept attributes mutable and introduced user.login_will_change! instead.

    I plan to make attributes frozen in Rails 2.2, though. In 2.1 I'll catch common mutators, typically on strings, and give a deprecation warning to give plenty of heads-up time before making the change.

    June 11th, 2008 @ 08:09 PM

  2. fhwang
    fhwang

    Is there one single place where this functionality -- as it exists now in Rails 2.1, and plans for the future -- is being documented? A pointer would be appreciated.

    And perhaps this is already answered there, but: Is it possible to turn off dirty tracking for one model, or for all of them? I can appreciate the functionality that comes with model dirtying but I would also hope that the design of ActiveRecord can accommodate those who think that the tradeoffs aren't worth it for them.

    June 11th, 2008 @ 08:27 PM

  3. Jeremy Kemper
    Jeremy Kemper

    There is no tradeoff. Simply do not use the tracking methods if you do not wish to. You can turn off partial updates, which use dirty tracking, with ActiveRecord::Base.partial_updates = false. It's a global switch.

    This feature and its ramifications are documented in ActiveRecord::Dirty.

    June 11th, 2008 @ 08:44 PM