class method self.method_missing

Ruby on Rails 3.1.12

Since v2.2.3 Last seen in v3.1.12 Private

Available in: v2.2.3 v2.3.18 v3.0.20 v3.1.12

Signature

self.method_missing(method_id, *arguments, &block)

Enables dynamic finders like User.find_by_user_name(user_name) and <tt>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.

Parameters

method_id req
arguments rest
block block
Source
# File activerecord/lib/active_record/base.rb, line 1058
        def method_missing(method_id, *arguments, &block)
          if match = DynamicFinderMatch.match(method_id)
            attribute_names = match.attribute_names
            super unless all_attributes_exists?(attribute_names)
            if !arguments.first.is_a?(Hash) && arguments.size < attribute_names.size
              ActiveSupport::Deprecation.warn(<<-eowarn)
Calling dynamic finder with less number of arguments than the number of attributes in the method name is deprecated and will raise an ArgumentError in the next version of Rails. Please pass `nil' explicitly to the arguments that are left out.
                eowarn
            end
            if match.finder?
              options = if arguments.length > attribute_names.size
                          arguments.extract_options!
                        else
                          {}
                        end
              relation = options.any? ? scoped(options) : scoped
              relation.send :find_by_attributes, match, attribute_names, *arguments
            elsif match.instantiator?
              scoped.send :find_or_instantiator_by_attributes, match, attribute_names, *arguments, &block
            end
          elsif match = DynamicScopeMatch.match(method_id)
            attribute_names = match.attribute_names
            super unless all_attributes_exists?(attribute_names)
            if arguments.size < attribute_names.size
              ActiveSupport::Deprecation.warn(
                "Calling dynamic scope with less number of arguments than the number of attributes in " \
                "the method name is deprecated and will raise an ArgumentError in the next version of Rails. " \
                "Please pass `nil' explicitly to the arguments that are left out."
              )
            end
            if match.scope?
              self.class_eval <<-METHOD, __FILE__, __LINE__ + 1
                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
              METHOD
              send(method_id, *arguments)
            end
          else
            super
          end
        end

Defined in activerecord/lib/active_record/base.rb line 1058 · View on GitHub · Improve this page · Find usages on GitHub

Defined in ActiveRecord::Base

Type at least 2 characters to search.

↑↓ navigate · open · esc close