Developers are often confused by what a callback is because of the name of the damned thing.
A callback function is a function which is:
- accessible by another function, and
- is invoked after the first function if that first function completes
A nice way of imagining how a callback function works is that it is a function that is "called at the back" of the function it is passed into.
Maybe a better name would be a "call after" function.
This construct is very useful for asynchronous behaviour where we want an activity to take place whenever a previous event completes.
Pseudocode:
// A function which accepts another function as an argument
// (and will automatically invoke that function when it completes - note that there is no explicit call to callbackFunction)
funct printANumber(int number, funct callbackFunction) {
printout("The number you provided is: " + number);
}
// a function which we will use in a driver function as a callback function
funct printFinishMessage() {
printout("I have finished printing numbers.");
}
// Driver method
funct event() {
printANumber(6, printFinishMessage);
}
Result if you called event():
The number you provided is: 6
I have finished printing numbers.
The order of the output here is important. Since callback functions are called afterwards, "I have finished printing numbers" is printed last, not first.
Callbacks are so-called due to their usage with pointer languages. If you don't use one of those, don't labour over the name 'callback'. Just understand that it is just a name to describe a method that's supplied as an argument to another method, such that when the parent method is called (whatever condition, such as a button click, a timer tick etc) and its method body completes, the callback function is then invoked.
Some languages support constructs where multiple callback function arguments are supported, and are called based on how the parent function completes (i.e. one callback is called in the event that the parent function completes successfully, another is called in the event that the parent function throws a specific error, etc).
ActiveRecord use to call after_save
callback each time save method is
called even if the model was not
changed and no insert/update query
spawned.
ActiveRecord executes :after_save callbacks each time the record is successfully saved regardless it was changed.
# record invalid, after_save not triggered
Record.new.save
# record valid, after_save triggered
r = Record.new(:attr => value)
# record valid and not changed, after_save triggered
r.save
What you want to know is if the record is changed, not if the record is saved.
You can easily accomplish this using record.changed?
class Record
after_save :do_something_if_changed
protected
def do_something_if_changed
if changed?
# ...
end
end
end
Best Answer
Rails 5.1+
Use
saved_change_to_published?
:Or if you prefer,
saved_change_to_attribute?(:published)
.Rails 3–5.1
In your
after_update
filter on the model you can use_changed?
accessor. So for example:It just works.