p((. _blatantly copied from "this email":http://article.gmane.org/gmane.comp.lang.ruby.rails/6099 by JeremyKemper on the "mailing list":http://lists.rubyonrails.org/mailman/listinfo/rails _

Timestamping callbacks are set up by default for columns named @created_at@/@created_on@ and @updated_at@/@updated_on@.  See http://rails.rubyonrails.com/classes/ActiveRecord/Timestamp.html


h2. Using callbacks

Callbacks let you set up "triggers" like this easily.  You can reimplement timestamping yourself:

<pre><code>
class Foo < ActiveRecord::Base
  before_create { |foo| foo.created_at = Time.now }
  before_save   { |foo| foo.updated_at = Time.now }
end
</code></pre>


h2. Package it in a module

Wonderful!  Now say we want timestamps in our other models.  Let's make a module to mix in the behavior:
<pre><code>
module Timestamped
  # Invoked when "include Timestamped" is called in base_class.
  def self.append_features(base_class)
    base_class.before_create { |model| model.created_at = Time.now }
    base_class.before_save   { |model| model.updated_at = Time.now }
  end
end
</code></pre>

It can now be mixed in to a model.

<pre><code>
class Foo < ActiveRecord::Base
  include Timestamped
end
</code></pre>


h2. Make it generic

Then say this is so useful we'd like to add it to _any models with these columns_:

*/lib/timestamped.rb*
<pre><code>
module Timestamped
  def self.append_features(base)
    base.before_create do |model|
      model.created_at ||= Time.now if model.respond_to?(:created_at)
    end
    base.before_save do |model|
      model.updated_at = Time.now if model.respond_to?(:updated_at)
    end
  end
end
</code></pre>

Extend ActiveRecord, which extends all of your models with this module.

*in /config/environment.rb*
<pre><code>
require 'timestamped'
class ActiveRecord::Base
  include Timestamped
end
</code></pre>

See UnderstandingWhatMethodsGoesWhere for further discussion about where these methods/modules could be placed.

category: Example
