@@ -46,6 +46,18 @@ module ClassMethods
4646 # column if it exists. Default is true
4747 #
4848 def has_paper_trail ( options = { } )
49+ options [ :on ] ||= [ :create , :update , :destroy ]
50+
51+ # Wrap the :on option in an array if necessary. This allows a single
52+ # symbol to be passed in.
53+ options [ :on ] = Array ( options [ :on ] )
54+
55+ setup_model_for_paper_trail ( options )
56+
57+ setup_callbacks_from_options options [ :on ]
58+ end
59+
60+ def setup_model_for_paper_trail ( options = { } )
4961 # Lazily include the instance methods so we don't clutter up
5062 # any more ActiveRecord models than we have to.
5163 send :include , InstanceMethods
@@ -60,6 +72,7 @@ def has_paper_trail(options = {})
6072 self . version_class_name = options [ :class_name ] || 'PaperTrail::Version'
6173
6274 class_attribute :paper_trail_options
75+
6376 self . paper_trail_options = options . dup
6477
6578 [ :ignore , :skip , :only ] . each do |k |
@@ -87,26 +100,53 @@ def has_paper_trail(options = {})
87100 :order => self . paper_trail_version_class . timestamp_sort_order
88101 end
89102
90- options [ :on ] ||= [ :create , :update , :destroy ]
91-
92- # Wrap the :on option in an array if necessary. This allows a single
93- # symbol to be passed in.
94- options_on = Array ( options [ :on ] )
95-
96- after_create :record_create , :if => :save_version? if options_on . include? ( :create )
97- if options_on . include? ( :update )
98- before_save :reset_timestamp_attrs_for_update_if_needed! , :on => :update
99- after_update :record_update , :if => :save_version?
100- after_update :clear_version_instance!
101- end
102- after_destroy :record_destroy , :if => :save_version? if options_on . include? ( :destroy )
103-
104103 # Reset the transaction id when the transaction is closed.
105104 after_commit :reset_transaction_id
106105 after_rollback :reset_transaction_id
107106 after_rollback :clear_rolled_back_versions
108107 end
109108
109+ def setup_callbacks_from_options ( options_on = [ ] )
110+ options_on . each do |option |
111+ send "paper_trail_on_#{ option } "
112+ end
113+ end
114+
115+ # Record version before or after "destroy" event
116+ def paper_trail_on_destroy ( recording_order = 'after' )
117+ unless %w[ after before ] . include? ( recording_order . to_s )
118+ fail ArgumentError , 'recording order can only be "after" or "before"'
119+ end
120+
121+ send "#{ recording_order } _destroy" ,
122+ :record_destroy ,
123+ :if => :save_version?
124+
125+ return if paper_trail_options [ :on ] . include? ( :destroy )
126+ paper_trail_options [ :on ] << :destroy
127+ end
128+
129+ # Record version after "update" event
130+ def paper_trail_on_update
131+ before_save :reset_timestamp_attrs_for_update_if_needed! ,
132+ :on => :update
133+ after_update :record_update ,
134+ :if => :save_version?
135+ after_update :clear_version_instance!
136+
137+ return if paper_trail_options [ :on ] . include? ( :update )
138+ paper_trail_options [ :on ] << :update
139+ end
140+
141+ # Record version after "create" event
142+ def paper_trail_on_create
143+ after_create :record_create ,
144+ :if => :save_version?
145+
146+ return if paper_trail_options [ :on ] . include? ( :create )
147+ paper_trail_options [ :on ] << :create
148+ end
149+
110150 # Switches PaperTrail off for this class.
111151 def paper_trail_off!
112152 PaperTrail . enabled_for_model ( self , false )
0 commit comments