class method
self.with_scope
Ruby on Rails 2.2.3
Since v2.2.3 Last seen in v3.1.12Signature
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_scopingopt = {} -
actionopt = :merge -
blockblock
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