I'd like to use before_save to perform an action (I won't get into the
details), but only the first time the record is changed from 0 to 1.
Here's the code I have so far in my model:
def before_save
if completed == 1
# perform the action
end
end
What the above does is perform the action when "completed" is set to
one, but the problem is I don't want this to happen every single time
there is a save. So what I'd like to be able to do is check the previous
value of "completed" and only perform the action if it used to be 0 and
is now 1. For example (psuedo code):
def before_save
if old_completed == 0 and completed == 1
# perform the action
end
end
How would I go about this? Obviously, I could add code outside the
model, but before_save seems like the nicest, cleanest place to for this
code to be. I searched this forum and found a post that kind of helps
answer my question, but it's not super clear and I'm still not sure what
the best solution is. It sounds like I have to do an external find just
to do this check, and that just doesn't seem right to me. Is that really
the only way?
Don't have a specific answer for you, but the acts_as_changed plugin might come in handy for you...
http://agilewebdevelopment.com/plugins/acts_as_changed
-philip
Philip Hallstrom wrote:
What the above does is perform the action when "completed" is set to
How would I go about this? Obviously, I could add code outside the
model, but before_save seems like the nicest, cleanest place to for this
code to be. I searched this forum and found a post that kind of helps
answer my question, but it's not super clear and I'm still not sure what
the best solution is. It sounds like I have to do an external find just
to do this check, and that just doesn't seem right to me. Is that really
the only way?
Don't have a specific answer for you, but the acts_as_changed plugin
might come in handy for you...
http://agilewebdevelopment.com/plugins/acts_as_changed
-philip
Thanks, Philip. I'm having a difficult time understanding exactly what
it does. The one line explanation isn't 100% clear to me. It sort of
looks like a speed related plug-in that simply updates fields that been
changed, rather than going through each field in the entire table, but I
could be wrong about that.
I've never used it myself
ANd I think you're right about that. There's a "changed_attributes" method that returns what's changed though that you could use perhaps...
Guess I thought it might provide more inspiration than an outright answer 
Thinking more about it, you could override the completed method to record that it was changed and then check that in your before_save...
-philip
Philip Hallstrom wrote:
changed, rather than going through each field in the entire table, but I
could be wrong about that.
I've never used it myself
ANd I think you're right about that.
There's a "changed_attributes" method that returns what's changed though
that you could use perhaps...
Guess I thought it might provide more inspiration than an outright
answer

Thinking more about it, you could override the completed method to
record
that it was changed and then check that in your before_save...
-philip
Sorry I'm a little late here -- been away for a couple days. That sounds
interesting. Can you explain in more detail how I'd do something like
that?
Hrm... something like this assuming your model has 'completed'
attribute.
class MyModel < ...
attr :is_complete
def completed=(val)
if completed == 0 && val == 1 then
is_complete = true
else
is_complete = false
end
completed = val
end
def before_save
if is_complete != true then
return false
end
true
end
end
MenDAKE :
My code looks something like this:
class MyModel < ActiveRecord::Base
attr :completed_is_changed
# This checks to see if the completed fiel was set to true for the
first time.
def completed=(val)
if completed == 0 && val == 1
completed_is_changed = true
else
completed_is_changed = false
end
completed = val
end
def before_save
if completed_is_changed == true
#perform the action.
end
end
The actions are performed, but the completed field value is
now never saved to the database. I would expect that the
line "completed = val" would take care of that, but it doesn't
seem to. Is something missing?
You can write it like that :
def completed=(val)
completed_is_changed = completed == 0 && val == 1
write_attribute(:completed, val)
end
-- Jean-François.
Philip Hallstrom wrote:
answer
that?
Hrm... something like this assuming your model has 'completed'
attribute.
class MyModel < ...
attr :is_complete
def completed=(val)
if completed == 0 && val == 1 then
is_complete = true
else
is_complete = false
end
completed = val
Ah, I suspect this is it... do something like...
self['completed'] = val
or whatever rails does by default for this thing...