Forum: Ruby on Rails Detect if an attribute was updated after save operation

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
05b76b92415862cc4783d09a9009641b?d=identicon&s=25 MrBanabas@googlemail.com (Guest)
on 2007-03-05 16:55
(Received via mailing list)
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
2017657725dd1bce83dc8a1e2e991d04?d=identicon&s=25 Luke Ivers (Guest)
on 2007-03-05 17:20
(Received via mailing list)
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
A99870c1391c39da2089649745965bda?d=identicon&s=25 Jean-François Trân (Guest)
on 2007-03-05 17:36
(Received via mailing list)
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_...

   -- Jean-François.

--
Ruby ( http://www.rubyfrance.org ) on Rails ( http://www.railsfrance.org
)
8310c5a7c769345114597bcdef111488?d=identicon&s=25 Ben Munat (Guest)
on 2007-03-05 19:41
(Received via mailing list)
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/Ca...
A2c85dc5ee81b12e3cc0a6522e8d079d?d=identicon&s=25 Chris Hall (au5lander)
on 2007-03-06 03:19
(Received via mailing list)
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.
05b76b92415862cc4783d09a9009641b?d=identicon&s=25 MrBanabas@googlemail.com (Guest)
on 2007-03-06 09:02
(Received via mailing list)
On Mar 6, 3:18 am, "Chris Hall" <christopher.k.h...@gmail.com> 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 :-)

--
Volker



--
Volker
A2c85dc5ee81b12e3cc0a6522e8d079d?d=identicon&s=25 Chris Hall (au5lander)
on 2007-03-07 18:28
(Received via mailing list)
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
2017657725dd1bce83dc8a1e2e991d04?d=identicon&s=25 Luke Ivers (Guest)
on 2007-03-07 18:43
(Received via mailing list)
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.
A2c85dc5ee81b12e3cc0a6522e8d079d?d=identicon&s=25 Chris Hall (au5lander)
on 2007-03-08 12:33
(Received via mailing list)
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
This topic is locked and can not be replied to.