diff options
author | José Valim <jose.valim@gmail.com> | 2010-06-29 17:18:55 +0200 |
---|---|---|
committer | José Valim <jose.valim@gmail.com> | 2010-06-29 17:18:55 +0200 |
commit | bd1666ad1de88598ed6f04ceffb8488a77be4385 (patch) | |
tree | 853cc5a1e6af361ed4fbb4af998099922f1e20c0 /activerecord/lib/active_record/named_scope.rb | |
parent | 9013227e00895ac95f29077229ec2fb156f450b0 (diff) | |
download | rails-bd1666ad1de88598ed6f04ceffb8488a77be4385.tar.gz rails-bd1666ad1de88598ed6f04ceffb8488a77be4385.tar.bz2 rails-bd1666ad1de88598ed6f04ceffb8488a77be4385.zip |
Add scoping and unscoped as the syntax to replace the old with_scope and with_exclusive_scope. A few examples:
* with_scope now should be scoping:
Before:
Comment.with_scope(:find => { :conditions => { :post_id => 1 } }) do
Comment.first #=> SELECT * FROM comments WHERE post_id = 1
end
After:
Comment.where(:post_id => 1).scoping do
Comment.first #=> SELECT * FROM comments WHERE post_id = 1
end
* with_exclusive_scope now should be unscoped:
class Post < ActiveRecord::Base
default_scope :published => true
end
Post.all #=> SELECT * FROM posts WHERE published = true
Before:
Post.with_exclusive_scope do
Post.all #=> SELECT * FROM posts
end
After:
Post.unscoped do
Post.all #=> SELECT * FROM posts
end
Notice you can also use unscoped without a block and it will return an anonymous scope with default_scope values:
Post.unscoped.all #=> SELECT * FROM posts
Diffstat (limited to 'activerecord/lib/active_record/named_scope.rb')
-rw-r--r-- | activerecord/lib/active_record/named_scope.rb | 33 |
1 files changed, 22 insertions, 11 deletions
diff --git a/activerecord/lib/active_record/named_scope.rb b/activerecord/lib/active_record/named_scope.rb index ec0a98c6df..c010dac64e 100644 --- a/activerecord/lib/active_record/named_scope.rb +++ b/activerecord/lib/active_record/named_scope.rb @@ -25,10 +25,9 @@ module ActiveRecord # # You can define a \scope that applies to all finders using # ActiveRecord::Base.default_scope. - def scoped(options = {}, &block) + def scoped(options = nil) if options.present? - relation = scoped.apply_finder_options(options) - block_given? ? relation.extending(Module.new(&block)) : relation + scoped.apply_finder_options(options) else current_scoped_methods ? unscoped.merge(current_scoped_methods) : unscoped.clone end @@ -88,18 +87,22 @@ module ActiveRecord # end def scope(name, scope_options = {}, &block) name = name.to_sym + valid_scope_name?(name) - if !scopes[name] && respond_to?(name, true) - logger.warn "Creating scope :#{name}. " \ - "Overwriting existing method #{self.name}.#{name}." - end + extension = Module.new(&block) if block_given? scopes[name] = lambda do |*args| options = scope_options.is_a?(Proc) ? scope_options.call(*args) : scope_options - relation = scoped - relation = options.is_a?(Hash) ? relation.apply_finder_options(options) : scoped.merge(options) if options - block_given? ? relation.extending(Module.new(&block)) : relation + relation = if options.is_a?(Hash) + scoped.apply_finder_options(options) + elsif options + scoped.merge(options) + else + scoped + end + + extension ? relation.extending(extension) : relation end singleton_class.send :define_method, name, &scopes[name] @@ -109,7 +112,15 @@ module ActiveRecord ActiveSupport::Deprecation.warn("Base.named_scope has been deprecated, please use Base.scope instead", caller) scope(*args, &block) end - end + protected + + def valid_scope_name?(name) + if !scopes[name] && respond_to?(name, true) + logger.warn "Creating scope :#{name}. " \ + "Overwriting existing method #{self.name}.#{name}." + end + end + end end end |