This project is archived and is in readonly mode.

#391 ✓invalid
fhwang

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

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

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.

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?

Comments and changes to this ticket

  • Jeremy Kemper

    Jeremy Kemper June 11th, 2008 @ 08:09 PM

    • 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.

  • fhwang

    fhwang June 11th, 2008 @ 08:27 PM

    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.

  • Jeremy Kemper

    Jeremy Kemper June 11th, 2008 @ 08:44 PM

    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.

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile »

<h2 style="font-size: 14px">Tickets have moved to Github</h2>

The new ticket tracker is available at <a href="https://github.com/rails/rails/issues">https://github.com/rails/rails/issues</a>

People watching this ticket

Pages