# File lib/active_support/callbacks.rb, line 106 def initialize(chain, filter, kind, options, klass) @chain, @kind, @klass = chain, kind, klass normalize_options!(options) @per_key = options.delete(:per_key) @raw_filter, @options = filter, options @filter = _compile_filter(filter) @compiled_options = _compile_options(options) @callback_id = next_id _compile_per_key_options end
# File lib/active_support/callbacks.rb, line 168 def _compile_per_key_options key_options = _compile_options(@per_key) @klass.class_eval def _one_time_conditions_valid_#{@callback_id}? true #{key_options[0]} end, __FILE__, __LINE__ + 1 end
# File lib/active_support/callbacks.rb, line 153 def _update_filter(filter_options, new_options) filter_options[:if].push(new_options[:unless]) if new_options.key?(:unless) filter_options[:unless].push(new_options[:if]) if new_options.key?(:if) end
# File lib/active_support/callbacks.rb, line 119 def clone(chain, klass) obj = super() obj.chain = chain obj.klass = klass obj.per_key = @per_key.dup obj.options = @options.dup obj.per_key[:if] = @per_key[:if].dup obj.per_key[:unless] = @per_key[:unless].dup obj.options[:if] = @options[:if].dup obj.options[:unless] = @options[:unless].dup obj end
This will supply contents for around and after filters, but not before filters (for the backward pass).
# File lib/active_support/callbacks.rb, line 234 def end(key=nil, object=nil) return if key && !object.send("_one_time_conditions_valid_#{@callback_id}?") if @kind == :around || @kind == :after # if condition # after_save :filter_name, :if => :condition # filter_name # end if @kind == :after [@compiled_options[0], @filter, @compiled_options[1]].compact.join("\n") else "end" end end end
# File lib/active_support/callbacks.rb, line 149 def matches?(_kind, _filter) @kind == _kind && @filter == _filter end
# File lib/active_support/callbacks.rb, line 141 def name chain.name end
# File lib/active_support/callbacks.rb, line 145 def next_id @@_callback_sequence += 1 end
# File lib/active_support/callbacks.rb, line 132 def normalize_options!(options) options[:if] = Array.wrap(options[:if]) options[:unless] = Array.wrap(options[:unless]) options[:per_key] ||= {} options[:per_key][:if] = Array.wrap(options[:per_key][:if]) options[:per_key][:unless] = Array.wrap(options[:per_key][:unless]) end
# File lib/active_support/callbacks.rb, line 158 def recompile!(_options, _per_key) _update_filter(self.options, _options) _update_filter(self.per_key, _per_key) @callback_id = next_id @filter = _compile_filter(@raw_filter) @compiled_options = _compile_options(@options) _compile_per_key_options end
This will supply contents for before and around filters, and no contents for after filters (for the forward pass).
# File lib/active_support/callbacks.rb, line 180 def start(key=nil, object=nil) return if key && !object.send("_one_time_conditions_valid_#{@callback_id}?") # options[0] is the compiled form of supplied conditions # options[1] is the "end" for the conditional # if @kind == :before || @kind == :around if @kind == :before # if condition # before_save :filter_name, :if => :condition # filter_name # end filter = unless halted result = #{@filter} halted = (#{chain.config[:terminator]}) end [@compiled_options[0], filter, @compiled_options[1]].compact.join("\n") else # Compile around filters with conditions into proxy methods # that contain the conditions. # # For `around_save :filter_name, :if => :condition': # # def _conditional_callback_save_17 # if condition # filter_name do # yield self # end # else # yield self # end # end # name = "_conditional_callback_#{@kind}_#{next_id}" @klass.class_eval def #{name}(halted) #{@compiled_options[0] || "if true"} && !halted #{@filter} do yield self end else yield self end end, __FILE__, __LINE__ + 1 "#{name}(halted) do" end end end
Generated with the Darkfish Rdoc Generator 2.