About callbacks: after_update

Hi, it would be great if someone could help me.
I’m using an after_update callback in a particular model to keep a
history of some object’s modifications. It works find but I have a
little inconvenient.
For some specific reasons, in the controller Ineed to do first an
object.update_attributes and then an object.save! and, as the
after_update callback it’s called after both instructions, for each time
I save an object, two modifications are recorded in the history.

One way to bypass this problem is to forget the callbacks and implement
something by myself but I don’t want to do that, at least not yet.

Can anyone give me a clue?

Thx

On Oct 2, 5:24 pm, Fernando P. [email protected]
wrote:

Hi, it would be great if someone could help me.
I’m using an after_update callback in a particular model to keep a
history of some object’s modifications. It works find but I have a
little inconvenient.
For some specific reasons, in the controller Ineed to do first an
object.update_attributes and then an object.save! and, as the
after_update callback it’s called after both instructions, for each time
I save an object, two modifications are recorded in the history.

You don’t need to call save at all: update_attributes automatically
saves the record.

Jeff

Thanks Jeff.
update_attribues(params[:my_object]) automatically saves the updated
params in the previous view but there are modifications that doesn’t
come directly from the previous view. For instance, I keep track of who
did the last modification or release the database record once it is
recorded.

if my_object.update_attributes(params[:my:object]) # after_update is
called
my_object.last_editor = current_user
my_object.locked = false
my_object.save! # after_update is called again
end

Any tip? Is there a way o keep all the modifications in memory and to
save it all at the same time? Thanks

Jeff C. wrote:

On Oct 2, 5:24 pm, Fernando P. [email protected]
wrote:

Hi, it would be great if someone could help me.
I’m using an after_update callback in a particular model to keep a
history of some object’s modifications. It works find but I have a
little inconvenient.
For some specific reasons, in the controller Ineed to do first an
object.update_attributes and then an object.save! and, as the
after_update callback it’s called after both instructions, for each time
I save an object, two modifications are recorded in the history.

You don’t need to call save at all: update_attributes automatically
saves the record.

Jeff
softiesonrails.com

On 3 Oct 2007, at 14:22, Fernando P. wrote:

called
my_object.last_editor = current_user
my_object.locked = false
my_object.save! # after_update is called again
end

Any tip? Is there a way o keep all the modifications in memory and to
save it all at the same time? Thanks

update_attributes just does attributes= and then saves so you could dp

my_object.last_editor = current_user
my_object.locked = false
my_object.update_attributes(params[:my:object])

or

my_object.attributes = params[:my:object]
if my_object.valid?
my_object.last_editor = current_user
my_object.locked = false
my_object.save! # after_update is called again
end

if you’re fussed about only setting locked/last_editor if the
attributes given were valid.

Fred

You can still use mass assignment, just change your logic a bit

@foo = Foo.find(params[:id]
@foo.attributes = params[:foo] # instead of update_attributes
if @foo.valid?
@my_object.last_editor = current_user
@my_object.locked = false
save!
end

However, if it were me… I’d make a model method

(in your model)

Saves the record by assigning fields

Requires you to pass the attributes, a user object, and a boolean

if @update_with_editor(params[:foo], current_user, false

else

render :action=>“edit”

end

def update_with_editor(attributes, last_editor, locked)
self.attributes = attributes
self.last_editor = last_editor
self.locked = locked
self.save
end

This makes it really easy to unit test.

If you need that in more than one model, put it in a library and use
Include
to mix it in.

  • YMMV… this code is untested and I don’t guarantee I didn’t make any
    foolish mistakes.

Thank you Fred and Brian. I really made it work as I wanted to.