Detect if an attribute was updated after save operation


#1

Hi,

I would like to perform some action if the value of a specific
attribute is changed during a save/update operation.
Unfortuently, I ve got no idea how to detect this.
Maybe somebody can explain the rails way to do it?
Thanks a lto in advance.


Volker


#2

Hi Volker,

I would like to perform some action if the value of a specific
attribute is changed during a save/update operation.
Unfortuently, I ve got no idea how to detect this.
Maybe somebody can explain the rails way to do it?

Have a look at acts_as_modified plugin :

http://agilewebdevelopment.com/plugins/acts_as_modified
http://svn.viney.net.nz/things/rails/plugins/acts_as_modified/

– Jean-François.


Ruby ( http://www.rubyfrance.org ) on Rails ( http://www.railsfrance.org
)


#3

Ok, I’m not 100% certain this is the best way to do this, but it’s the
first
thing that came to mind:

In your model, say the field ‘title’ is the one you want to monitor…
then
you can do this:

def title=(arg)
@old_title = self.title
self[:title] = arg
end

And also this:
def after_save
if not @old_title.nil? and @old_title != self.title
#do some stuff because the value changed here
@old_title = nil #make sure, if we re-use this same object, that
this
stuff doesn’t happen again unless the value is re-changed
end
end


#4

if all you want is to check the value of a specific attribute prior to
saving, then a before_save callback should suffice.

if you need to monitor the state of the model as a whole, the
acts_as_modified plugin is probably what you want.


#5

Jean-François Trân wrote:

Before resorting to a plugin, you might do some research on rails
Observers [1] and/or the ActiveRecord lifecycle methods [2] (after_save,
after_update, etc.). Both are covered in the Agile book and in the rails
docs.

b

[1] http://ar.rubyonrails.com/classes/ActiveRecord/Observer.html
[2] http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html


#6

On Mar 6, 3:18 am, “Chris H.” removed_email_address@domain.invalid wrote:

if all you want is to check the value of a specific attribute prior to
saving, then a before_save callback should suffice.

Well, no we are getting to the interesting part…
I m in a before_save callback. how to access the new and the old value
in before_save… ?
Is that possible?

Sorry for these basic questions, I just want to make sure that I m
using the easiest way to implement it…
I ve searched already some news groups but so far it seems that
before_save has already stored the new values and no way to see the
old values by just accessing some array…
So, I ve nly seen the two possibilities:
a) store the old value in a self implemented accessor
b) request the record from the database again in before_save…

I was hoping for a c) like… well just do self[:name].old_value :slight_smile:


Volker


Volker


#7

you’d have to query the db to get the old data

i’ve never tried this, so i may be off, but i imagine it would be
something like:

def before_save
old_obj = Model.find(self.id)

compare self to old_obj


end


#8

I think you would be better off using an accessor like I showed in my
earlier response… just
def title=(blah)
@old_title = self.title
self[:title] = blah
end

then in your before_save you can compare vs that and set it to nil
aftewards… if you do what Chris is suggesting, it’s another trip to
the DB
every time you try to save one of these models.


#9

true.

the only issue i see, and it would probably never happen, is if you
changed the attribute more than once before saving. you would lose
the original value of the attribute. a fix for that might be:

def title=(blah)

who cares how many times it is changed

just record the original

@old_title = self.title unless @old_title
self[:title] = blah
end

def title_changed?
(@old_title && @old_title != self.title)
end