class method self.with_scope

Ruby on Rails 2.2.3

Since v2.2.3 Last seen in v3.1.12

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

Signature

self.with_scope(method_scoping = {}, action = :merge, &block)

Scope parameters to method calls within the block. Takes a hash of method_name => parameters hash. method_name may be :find or :create. :find parameters may include the :conditions, :joins, :include, :offset, :limit, and :readonly options. :create parameters are an attributes hash.

class Article < ActiveRecord::Base
  def self.create_with_scope
    with_scope(:find => { :conditions => "blog_id = 1" }, :create => { :blog_id => 1 }) do
      find(1) # => SELECT * from articles WHERE blog_id = 1 AND id = 1
      a = create(1)
      a.blog_id # => 1
    end
  end
end

In nested scopings, all previous parameters are overwritten by the innermost rule, with the exception of :conditions and :include options in :find, which are merged.

class Article < ActiveRecord::Base
  def self.find_with_scope
    with_scope(:find => { :conditions => "blog_id = 1", :limit => 1 }, :create => { :blog_id => 1 }) do
      with_scope(:find => { :limit => 10 })
        find(:all) # => SELECT * from articles WHERE blog_id = 1 LIMIT 10
      end
      with_scope(:find => { :conditions => "author_id = 3" })
        find(:all) # => SELECT * from articles WHERE blog_id = 1 AND author_id = 3 LIMIT 1
      end
    end
  end
end

You can ignore any previous scopings by using the with_exclusive_scope method.

class Article < ActiveRecord::Base
  def self.find_with_exclusive_scope
    with_scope(:find => { :conditions => "blog_id = 1", :limit => 1 }) do
      with_exclusive_scope(:find => { :limit => 10 })
        find(:all) # => SELECT * from articles LIMIT 10
      end
    end
  end
end

Note: the :find scope also has effect on update and deletion methods, like update_all and delete_all.

Parameters

method_scoping opt = {}
action opt = :merge
block block
Source
# File activerecord/lib/active_record/base.rb, line 1958
        def with_scope(method_scoping = {}, action = :merge, &block)
          method_scoping = method_scoping.method_scoping if method_scoping.respond_to?(:method_scoping)

          # Dup first and second level of hash (method and params).
          method_scoping = method_scoping.inject({}) do |hash, (method, params)|
            hash[method] = (params == true) ? params : params.dup
            hash
          end

          method_scoping.assert_valid_keys([ :find, :create ])

          if f = method_scoping[:find]
            f.assert_valid_keys(VALID_FIND_OPTIONS)
            set_readonly_option! f
          end

          # Merge scopings
          if action == :merge && current_scoped_methods
            method_scoping = current_scoped_methods.inject(method_scoping) do |hash, (method, params)|
              case hash[method]
                when Hash
                  if method == :find
                    (hash[method].keys + params.keys).uniq.each do |key|
                      merge = hash[method][key] && params[key] # merge if both scopes have the same key
                      if key == :conditions && merge
                        hash[method][key] = merge_conditions(params[key], hash[method][key])
                      elsif key == :include && merge
                        hash[method][key] = merge_includes(hash[method][key], params[key]).uniq
                      elsif key == :joins && merge
                        hash[method][key] = merge_joins(params[key], hash[method][key])
                      else
                        hash[method][key] = hash[method][key] || params[key]
                      end
                    end
                  else
                    hash[method] = params.merge(hash[method])
                  end
                else
                  hash[method] = params
              end
              hash
            end
          end

          self.scoped_methods << method_scoping

          begin
            yield
          ensure
            self.scoped_methods.pop
          end
        end

Defined in activerecord/lib/active_record/base.rb line 1958 · 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