diff options
-rw-r--r-- | activerecord/lib/active_record/named_scope.rb | 52 | ||||
-rw-r--r-- | activerecord/lib/active_record/relation.rb | 11 | ||||
-rw-r--r-- | activerecord/lib/active_record/relation/predicate_builder.rb | 2 |
3 files changed, 29 insertions, 36 deletions
diff --git a/activerecord/lib/active_record/named_scope.rb b/activerecord/lib/active_record/named_scope.rb index be26b1f47f..d56f7afb74 100644 --- a/activerecord/lib/active_record/named_scope.rb +++ b/activerecord/lib/active_record/named_scope.rb @@ -25,7 +25,8 @@ module ActiveRecord # You can define a scope that applies to all finders using ActiveRecord::Base.default_scope. def scoped(options = {}, &block) if options.present? - Scope.init(self, options, &block) + relation = scoped.apply_finder_options(options) + block_given? ? relation.extending(Module.new(&block)) : relation else current_scoped_methods ? unscoped.merge(current_scoped_methods) : unscoped.clone end @@ -107,13 +108,22 @@ module ActiveRecord end scopes[name] = lambda do |parent_scope, *args| - Scope.init(parent_scope, case options - when Hash, Relation - options - when Proc - options.call(*args) - end, &block) + scope_options = case options + when Hash, Relation + options + when Proc + options.call(*args) + end + + relation = if scope_options.is_a?(Hash) + parent_scope.scoped.apply_finder_options(scope_options) + else + scope_options ? parent_scope.scoped.merge(scope_options) : parent_scope.scoped + end + + block_given? ? relation.extending(Module.new(&block)) : relation end + singleton_class.instance_eval do define_method name do |*args| scopes[name].call(self, *args) @@ -127,33 +137,5 @@ module ActiveRecord end end - class Scope < Relation - delegate :scopes, :with_scope, :with_exclusive_scope, :scoped_methods, :scoped, :to => :klass - - def self.init(klass, options, &block) - relation = new(klass, klass.arel_table, &block) - - scope = if options.is_a?(Hash) - klass.scoped.apply_finder_options(options) - else - options ? klass.scoped.merge(options) : klass.scoped - end - - relation.merge(scope) - end - - def ==(other) - case other - when Scope - to_sql == other.to_sql - when Relation - other == self - when Array - to_a == other.to_a - end - end - - end - end end diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb index 3ca27f06ea..69d04d7375 100644 --- a/activerecord/lib/active_record/relation.rb +++ b/activerecord/lib/active_record/relation.rb @@ -311,11 +311,22 @@ module ActiveRecord @should_eager_load ||= (@eager_load_values.any? || (@includes_values.any? && references_eager_loaded_tables?)) end + def ==(other) + case other + when Relation + other.to_sql == to_sql + when Array + to_a == other.to_a + end + end + protected def method_missing(method, *args, &block) if Array.method_defined?(method) to_a.send(method, *args, &block) + elsif @klass.scopes[method] + merge(@klass.send(method, *args, &block)) elsif @klass.respond_to?(method) @klass.send(:with_scope, self) { @klass.send(method, *args, &block) } elsif arel.respond_to?(method) diff --git a/activerecord/lib/active_record/relation/predicate_builder.rb b/activerecord/lib/active_record/relation/predicate_builder.rb index 711df16bf1..717756418c 100644 --- a/activerecord/lib/active_record/relation/predicate_builder.rb +++ b/activerecord/lib/active_record/relation/predicate_builder.rb @@ -23,7 +23,7 @@ module ActiveRecord attribute = table[column] case value - when Array, ActiveRecord::Associations::AssociationCollection, ActiveRecord::NamedScope::Scope + when Array, ActiveRecord::Associations::AssociationCollection, ActiveRecord::Relation values = value.to_a attribute.in(values) when Range |