diff options
Diffstat (limited to 'activerecord/lib/active_record/scoping/named.rb')
-rw-r--r-- | activerecord/lib/active_record/scoping/named.rb | 47 |
1 files changed, 19 insertions, 28 deletions
diff --git a/activerecord/lib/active_record/scoping/named.rb b/activerecord/lib/active_record/scoping/named.rb index 8b7eda6eee..35420e6551 100644 --- a/activerecord/lib/active_record/scoping/named.rb +++ b/activerecord/lib/active_record/scoping/named.rb @@ -25,22 +25,18 @@ module ActiveRecord if current_scope current_scope.clone else - scope = relation - scope.default_scoped = true - scope + default_scoped end end + def default_scoped # :nodoc: + relation.merge(build_default_scope) + end + # Collects attributes from scopes that should be applied when creating # an AR instance for the particular class this is called on. def scope_attributes # :nodoc: - if current_scope - current_scope.scope_for_create - else - scope = relation - scope.default_scoped = true - scope.scope_for_create - end + all.scope_for_create end # Are there default attributes associated with this scope? @@ -134,37 +130,32 @@ module ActiveRecord # end # # def self.titles - # map(&:title) + # pluck(:title) # end - # # end # # We are able to call the methods like this: # # Article.published.featured.latest_article # Article.featured.titles - def scope(name, body, &block) - extension = Module.new(&block) if block + unless body.respond_to?(:call) + raise ArgumentError, 'The scope body needs to be callable.' + end - # Check body.is_a?(Relation) to prevent the relation actually being - # loaded by respond_to? - if body.is_a?(Relation) || !body.respond_to?(:call) - ActiveSupport::Deprecation.warn( - "Using #scope without passing a callable object is deprecated. For " \ - "example `scope :red, where(color: 'red')` should be changed to " \ - "`scope :red, -> { where(color: 'red') }`. There are numerous gotchas " \ - "in the former usage and it makes the implementation more complicated " \ - "and buggy. (If you prefer, you can just define a class method named " \ - "`self.red`.)" - ) + if dangerous_class_method?(name) + raise ArgumentError, "You tried to define a scope named \"#{name}\" " \ + "on the model \"#{self.name}\", but Active Record already defined " \ + "a class method with the same name." end + extension = Module.new(&block) if block + singleton_class.send(:define_method, name) do |*args| - options = body.respond_to?(:call) ? unscoped { body.call(*args) } : body - relation = all.merge(options) + scope = all.scoping { body.call(*args) } + scope = scope.extending(extension) if extension - extension ? relation.extending(extension) : relation + scope || all end end end |