1 # -*- coding: utf-8 -*-
4 # 作成時および更新時の情報を記録するモジュール。
7 def self.included(base) # :ndoc:
8 base.extend(ClassMethods)
13 # モデルクラスで呼び出すことにより指定した対象の状況を記録するようになる。
15 # <tt>monitor</tt> : 記録する対象のモデルクラスの名前を指定する。
16 # デフォルトは <tt>User</tt>
17 # ここで使用するモデルクラスには current_id というクラスメソッドが
20 def context_monitor(target_model_name = :user, options = {})
21 model_name = target_model_name.to_s.capitalize
22 suffix = (options[:suffix] || 'by').to_s
23 created = 'created_' + suffix
24 updated = 'updated_' + suffix
27 callbacks = Callbacks.new(model_name, created, updated)
28 before_create callbacks
29 before_update callbacks
30 belongs_to created, :class_name => model_name, :foreign_key => "#{created}_id"
31 belongs_to updated, :class_name => model_name, :foreign_key => "#{updated}_id"
34 alias monitor context_monitor
37 class Callbacks # :ndoc: all
38 def initialize(model_name, created, updated)
39 @model = model_name.constantize
40 @created_id = "#{created}_id"
41 @updated_id = "#{updated}_id"
43 def before_create(record)
44 record.write_attribute(@created_id, @model.current_id) if include_column_and_nil?(record, @created_id)
47 def before_update(record)
48 record.write_attribute(@updated_id, @model.current_id) if include_column?(record, @updated_id)
52 def column_names(record)
53 @column_names ||= record.class.column_names
56 def include_column?(record, column)
57 column_names(record).include? column
60 def include_column_and_nil?(record, column)
61 include_column?(record, column) && record.read_attribute(column).nil?
67 ActiveRecord::Base.__send__(:include, ActiveRecord::ContextMonitor)