This project is archived and is in readonly mode.
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 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 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 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>