Files

Class Index [+]

Quicksearch

ActiveRecord::Scoping::ClassMethods

Public Instance Methods

with_scope(scope = {}, action = :merge, &block) click to toggle source

with_scope lets you apply options to inner block incrementally. It takes a hash and the keys must be :find or :create. :find parameter is Relation while :create parameters are an attributes hash.

  class Article < ActiveRecord::Base
    def self.create_with_scope
      with_scope(:find => where(: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 where, includes, and joins operations in Relation, which are merged.

joins operations are uniqued so multiple scopes can join in the same table without table aliasing problems. If you need to join multiple tables, but still want one of the tables to be uniqued, use the array of strings format for your joins.

  class Article < ActiveRecord::Base
    def self.find_with_scope
      with_scope(:find => where(:blog_id => 1).limit(1), :create => { :blog_id => 1 }) do
        with_scope(:find => limit(10)) do
          all # => SELECT * from articles WHERE blog_id = 1 LIMIT 10
        end
        with_scope(:find => where(:author_id => 3)) do
          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 => where(:blog_id => 1).limit(1)) do
        with_exclusive_scope(:find => limit(10)) do
          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.

     # File lib/active_record/scoping.rb, line 60
 60:       def with_scope(scope = {}, action = :merge, &block)
 61:         # If another Active Record class has been passed in, get its current scope
 62:         scope = scope.current_scope if !scope.is_a?(Relation) && scope.respond_to?(:current_scope)
 63: 
 64:         previous_scope = self.current_scope
 65: 
 66:         if scope.is_a?(Hash)
 67:           # Dup first and second level of hash (method and params).
 68:           scope = scope.dup
 69:           scope.each do |method, params|
 70:             scope[method] = params.dup unless params == true
 71:           end
 72: 
 73:           scope.assert_valid_keys([ :find, :create ])
 74:           relation = construct_finder_arel(scope[:find] || {})
 75:           relation.default_scoped = true unless action == :overwrite
 76: 
 77:           if previous_scope && previous_scope.create_with_value && scope[:create]
 78:             scope_for_create = if action == :merge
 79:               previous_scope.create_with_value.merge(scope[:create])
 80:             else
 81:               scope[:create]
 82:             end
 83: 
 84:             relation = relation.create_with(scope_for_create)
 85:           else
 86:             scope_for_create = scope[:create]
 87:             scope_for_create ||= previous_scope.create_with_value if previous_scope
 88:             relation = relation.create_with(scope_for_create) if scope_for_create
 89:           end
 90: 
 91:           scope = relation
 92:         end
 93: 
 94:         scope = previous_scope.merge(scope) if previous_scope && action == :merge
 95: 
 96:         self.current_scope = scope
 97:         begin
 98:           yield
 99:         ensure
100:           self.current_scope = previous_scope
101:         end
102:       end

Protected Instance Methods

with_exclusive_scope(method_scoping = {}, &block) click to toggle source

Works like with_scope, but discards any nested properties.

     # File lib/active_record/scoping.rb, line 107
107:       def with_exclusive_scope(method_scoping = {}, &block)
108:         if method_scoping.values.any? { |e| e.is_a?(ActiveRecord::Relation) }
109:           raise ArgumentError,   New finder API can not be used with_exclusive_scope. You can either call unscoped to get an anonymous scope not bound to the default_scope:  User.unscoped.where(:active => true)  Or call unscoped with a block:  User.unscoped do  User.where(:active => true).all  end
110:         end
111:         with_scope(method_scoping, :overwrite, &block)
112:       end

Private Instance Methods

construct_finder_arel(options = {}, scope = nil) click to toggle source
     # File lib/active_record/scoping.rb, line 135
135:       def construct_finder_arel(options = {}, scope = nil)
136:         relation = options.is_a?(Hash) ? unscoped.apply_finder_options(options) : options
137:         relation = scope.merge(relation) if scope
138:         relation
139:       end

Disabled; run with --debug to generate this.

[Validate]

Generated with the Darkfish Rdoc Generator 1.1.6.