This project is archived and is in readonly mode.
Rails 2.3.2 dirty tracking has error when Observable is included
Reported by apathy in action | February 25th, 2010 @ 06:13 PM
Ruby 1.8.6,
Rails 2.3.2
Windows xp.
The Observable module and the ActiveRecord::Dirty module appear to be incompatible when the Observable module is included in an ActiveRecord subclass. This results in a NoMethodError being thrown in ActiveRecord::Base#attributes_with_quotes(..) which assumes an Enumerable in its third parameter.
Steps to recreate (using Oracle in this instance):
create table Foo
( id number(9), created_at date, updated_at date );
class Foo < ActiveRecord::Base
end
f=Foo.new()
f.id=(1)
f.save()
f=Foo.first()
f.changed()
=> [] f.changed?
=> false f.id=(2)
=> 2 f.changed()
=> ["id"] f.changed?
=> true
This is the expected behaviour with dirty tracking.
Foo.send( :include, Observable )
f=Foo.first()
=> Foo(created_at: datetime, updated_at: datetime, id: integer)
b.changed()
=> true b.changed?
=> true
The Observable module's implementations of #changed and
#changed? replace those of ActiveRecord::Dirty module.
This can cause an error down in the
ActiveRecord::Base#attributes_with_quotes method which expects an
Enumerable as its #attribute_names parameter, resulting in a
NoMethodError on TrueClass being sent #each.
This comes about due to the above inclusion of Observable which causes the ActiveRecord::Dirty module's #changed implementation to be overridden and return a boolean which changes the following when #partial_updates are enabled (the default):
def update_with_dirty
if partial_updates?
# Serialized attributes should always be written in case they've been
# changed in place.
update_without_dirty(changed | self.class.serialized_attributes.keys)
else
update_without_dirty
end
end
The workaround in our case was to set #partial_updates to false
for any class which included Observable.
One fix is to alter the true block to :
update_without_dirty( changed_attributes().keys() | self.class.serialized_attributes.keys )
This prevents the NoMethodError from occurring.
The behavior described here does not appear to be present in
2.3.4.
Hope this helps.
sinclair
(ps. tried to use formatting around the code but things went
pear-shaped, sorry.)
Comments and changes to this ticket
-
Andrea Campi October 16th, 2010 @ 11:50 PM
- Tag changed from rails 2.3.2 activerecord dirty observable changed nomethoderror to 2.3.2, activerecord, dirty, nomethoderror, observable
-
Ryan Bigg October 17th, 2010 @ 07:43 AM
- State changed from new to stale
- Importance changed from to Low
Please comment on this ticket if this is still an issue with 2.3.10.
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>