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.

ActiveRecord::Base#changed returns empty when attribute set during after_create

#1981

This is an abstracted version of my actual problem, but it reproduces in the same way.

I have a model:


class MultiSave < ActiveRecord::Base
	
	after_create :overwrite_id_dependant
	
	def overwrite_id_dependant
		write_attribute(:id_dependant, id * 5)
	end
	
	def name=(value)
		write_attribute :name, value
		write_attribute :name_dependant, value + " rocks"
	end
end

When I run it using script/server I get the following results

Loading development environment (Rails 2.2.2)
>> m = MultiSave.new(:name => 'slurm')
=> #<MultiSave id: nil, id_dependant: nil, name: "slurm", name_dependant: "slurm rocks", created_at: nil, updated_at: nil>
>> m
=> #<MultiSave id: nil, id_dependant: nil, name: "slurm", name_dependant: "slurm rocks", created_at: nil, updated_at: nil>
>> m.changed
=> ["name", "name_dependant"]
>> m.save!
=> true
>> m
=> #<MultiSave id: 11, id_dependant: 55, name: "slurm", name_dependant: "slurm rocks", created_at: "2009-02-16 00:42:34", updated_at: "2009-02-16 00:42:34">
>> m.changed
=> []
>> m.save!
=> true
>> m2 = MultiSave.find(11)
=> #<MultiSave id: 11, id_dependant: nil, name: "slurm", name_dependant: "slurm rocks", created_at: "2009-02-16 00:42:34", updated_at: "2009-02-16 00:42:34">

I have attached the rails project to this bug.  It exhibits the save behavior if you change to model to use after_save.

Reported by Mike Emery · February 16th, 2009 @ 12:54 AM

State: invalid
Milestone: 2.x
Assigned to: Ryan Bigg Ryan Bigg
Importance: none

Activity

  1. Matt Jones
    Matt Jones

    I'm not sure that this is a bug - the possible uses seem very limited. The problem is arising from the partial update / dirty checking code in dirty.rb; the list of changed fields is cleared after a save is completed. That, combined with partial updates, means that the changes in overwrite_id_dependant don't get written out.

    The short, quick solution to this is to use update_attribute rather than write_attribute; this will save the field immediately to the DB. Is there a reason why this won't work in your app, Mike?

    February 16th, 2009 @ 01:35 AM

  2. Steve St. Martin
    Steve St. Martin
    • Assigned user set to Ryan Bigg

    agreed, not really a bug. author never responded should be marked as invalid or needs-more-info

    April 15th, 2010 @ 08:46 PM

  3. Ryan Bigg
    Ryan Bigg
    • State changed from new to invalid

    Matt Jones' solution seems worthwhile.

    April 15th, 2010 @ 10:50 PM