Showing posts with label Callbacks. Show all posts
Showing posts with label Callbacks. Show all posts

Sunday, August 26, 2007

model callbacks of Rails ActiveRecord


class Encrypter
def before_save(model)
model.name.tr! 'a-z', 'b-za'
end

def after_save(model)
model.name.tr! 'b-za', 'a-z'
end

# alias_method :after_find, :after_save
# alias_method
# Makes new_id a new copy of the method old_id. This can be used to retain access to
# methods that are overridden.

alias after_find after_save
# Aliasing
# alias new_name old_name
# creates a new name that refers to an existing method, operator, global variable, or reg-
# ular expression backreference ($&, $`, $', and $+). Local variables, instance variables,
# class variables, and constants may not be aliased. The parameters to alias may be
# names or symbols.

end

class ActiveRecord::Base
def self.encrypted
encrypt = Encrypter.new
before_save encrypt
after_save encrypt
after_find encrypt
module_eval <<-"end_eval"
def after_find
# Unlike all the other callbacks, after_find and after_initialize will only be run
# if an explicit implementation is defined (def after_find).
end
end_eval
end
end

class User < ActiveRecord::Base
encrypted
protected
def validate_on_create()
puts 'existed user name' if self.class.exists? :name => name
end
end

Saturday, August 25, 2007

Rails callbacks explain

source article

Callbacks


From the API documentation, "Callbacks are hooks into the lifecycle of an Active Record object that allows you to trigger logic before or after an alteration of the object state." There are callbacks for: validate, create, save, update, destroy, find, new/initialize, and associations (Association Callbacks are discussed in the Associations section below).



You may configure most of these callbacks (excluding find, initialize, and association callbacks) in two different ways: (1) overwrite the default method or (2) register with the macros. The macros are more powerful and more commonly used, especially as the macros add their behavior into a callback hierarchy that is maintained through a class inheritance hierarchy. That is, if you register callbacks for the Animal class (which inherits from ActiveRecord::Base) and subsequently define a Monkey class (which inherits from Animal), then Monkey will also inherit the Animal callbacks.



The callback macros can be used in four different ways (see the very clear discussion in the "Types of callbacks" section on the ActiveRecord::Callbacks API page)


  1. symbol reference to a protected or private method in the model

  2. an object to be messaged with the callback method and record

  3. a method string

  4. a method Proc



The validation callback hierarchy



These series are triggered by calls to:
object.valid?

New Record Existing Record
----------------------------- -----------------------------
before_validation before_validation
before_validation_on_create before_validation_on_update
<< object validated here >> << object validated here >>
after_validation after_validation
after_validation_on_create after_validation_on_update



This series is triggered by calls to:
Model.create
object.save (if not previously saved)

before_validation
before_validation_on_create
<< object validated here >>
after_validation
after_validation_on_create
before_save
before_create
<< db record created here >>
after_create
after_save



This series is triggered by calls to:
object.save (if previously saved)
object.update_attributes

before_validation
before_validation_on_update
<< object validated here >>
after_validation
after_validation_on_update
before_save
before_update
<< db record saved/updated here >>
after_update
after_save

A save! call triggers the validation series twice. If save! is called on a new record, the new record validation series with *_on_create methods is called twice.



This series is triggered by calls to:
object.save!

before_validation
before_validation_on_update
<< object validated here >>
after_validation
after_validation_on_update
before_validation
before_validation_on_update
<< object validated here >>
after_validation
after_validation_on_update
before_save
before_update
<< db record saved/updated here >>
after_update
after_save

Several of the save/update methods appear to bypass validation (or at least the validation callbacks) and only call the save callbacks.



This series is triggered by calls to:
object.increment!
object.decrement!
object.toggle!
object.update_attribute

before_save
before_update
<< db record saved/updated here >>
after_update
after_save

The object.update callback hierarchy only triggers the update callbacks.



This series is triggered by calls to:
object.update

before_update
<< db record updated here >>
after_update

However, the model update class method triggers a full series of callbacks.



This series is triggered by calls to:
Model.update

after_find (if defined)
after_initialize (if defined)
before_validation
before_validation_on_update
<< object validated here >>
after_validation
after_validation_on_update
before_save
before_update
<< db record saved/updated here >>
after_update
after_save

increment_counter and decrement_counter bypass all callbacks



These methods bypass all callbacks:
Model.decrement_counter
Model.increment_counter



This series is triggered by calls to:
object.destroy

before_destroy
<< record is deleted here >>
after_destroy

This series is triggered by calls to:
Model.destroy
Model.destroy_all

after_find (if defined)
after_initialize (if defined)
before_destroy
<< record is deleted here >>
after_destroy

These don't trigger any callbacks:
Model.delete
Model.delete_all

The after_find and after_initialize callbacks may will only be called if the default method is overwritten (no macros here).



Triggered by a call to:
Model.new

after_initialize (if defined)

--------------------------------------------

Triggered by a call to:
object.reload
Model.find

after_find (if defined)
after_initialize (if defined)