Files

Class Index [+]

Quicksearch

ActiveRecord::DynamicMatchers

Public Instance Methods

respond_to?(method_id, include_private = false) click to toggle source
    # File lib/active_record/dynamic_matchers.rb, line 3
 3:     def respond_to?(method_id, include_private = false)
 4:       if match = DynamicFinderMatch.match(method_id)
 5:         return true if all_attributes_exists?(match.attribute_names)
 6:       elsif match = DynamicScopeMatch.match(method_id)
 7:         return true if all_attributes_exists?(match.attribute_names)
 8:       end
 9: 
10:       super
11:     end

Private Instance Methods

aggregate_mapping(reflection) click to toggle source
    # File lib/active_record/dynamic_matchers.rb, line 77
77:     def aggregate_mapping(reflection)
78:       mapping = reflection.options[:mapping] || [reflection.name, reflection.name]
79:       mapping.first.is_a?(Array) ? mapping : [mapping]
80:     end
all_attributes_exists?(attribute_names) click to toggle source
    # File lib/active_record/dynamic_matchers.rb, line 72
72:     def all_attributes_exists?(attribute_names)
73:       (expand_attribute_names_for_aggregates(attribute_names) -
74:        column_methods_hash.keys).empty?
75:     end
expand_attribute_names_for_aggregates(attribute_names) click to toggle source

Similar in purpose to expand_hash_conditions_for_aggregates.

    # File lib/active_record/dynamic_matchers.rb, line 60
60:     def expand_attribute_names_for_aggregates(attribute_names)
61:       attribute_names.map { |attribute_name|
62:         unless (aggregation = reflect_on_aggregation(attribute_name.to_sym)).nil?
63:           aggregate_mapping(aggregation).map do |field_attr, _|
64:             field_attr.to_sym
65:           end
66:         else
67:           attribute_name.to_sym
68:         end
69:       }.flatten
70:     end
method_missing(method_id, *arguments, &block) click to toggle source

Enables dynamic finders like User.find_by_user_name(user_name) and User.scoped_by_user_name(user_name). Refer to Dynamic attribute-based finders section at the top of this file for more detailed information.

It’s even possible to use all the additional parameters to find. For example, the full interface for find_all_by_amount is actually find_all_by_amount(amount, options).

Each dynamic finder using scoped_by_* is also defined in the class after it is first invoked, so that future attempts to use it do not run through method_missing.

    # File lib/active_record/dynamic_matchers.rb, line 24
24:     def method_missing(method_id, *arguments, &block)
25:       if match = (DynamicFinderMatch.match(method_id) || DynamicScopeMatch.match(method_id))
26:         attribute_names = match.attribute_names
27:         super unless all_attributes_exists?(attribute_names)
28:         if !(match.is_a?(DynamicFinderMatch) && match.instantiator? && arguments.first.is_a?(Hash)) && arguments.size < attribute_names.size
29:           method_trace = "#{__FILE__}:#{__LINE__}:in `#{method_id}'"
30:           backtrace = [method_trace] + caller
31:           raise ArgumentError, "wrong number of arguments (#{arguments.size} for #{attribute_names.size})", backtrace
32:         end
33:         if match.respond_to?(:scope?) && match.scope?
34:           self.class_eval             def self.#{method_id}(*args)                                    # def self.scoped_by_user_name_and_password(*args)              attributes = Hash[[:#{attribute_names.join(',:')}].zip(args)] #   attributes = Hash[[:user_name, :password].zip(args)]                                                                            #              scoped(:conditions => attributes)                             #   scoped(:conditions => attributes)            end                                                             # end, __FILE__, __LINE__ + 1
35:           send(method_id, *arguments)
36:         elsif match.finder?
37:           options = if arguments.length > attribute_names.size
38:                       arguments.extract_options!
39:                     else
40:                       {}
41:                     end
42: 
43:           relation = options.any? ? scoped(options) : scoped
44:           relation.send :find_by_attributes, match, attribute_names, *arguments, &block
45:         elsif match.instantiator?
46:           scoped.send :find_or_instantiator_by_attributes, match, attribute_names, *arguments, &block
47:         end
48:       else
49:         super
50:       end
51:     end

Disabled; run with --debug to generate this.

[Validate]

Generated with the Darkfish Rdoc Generator 1.1.6.