diff --git a/activerecord/lib/active_record/named_scope.rb b/activerecord/lib/active_record/named_scope.rb index 60ff4b5..f90afbf 100644 --- a/activerecord/lib/active_record/named_scope.rb +++ b/activerecord/lib/active_record/named_scope.rb @@ -101,7 +101,7 @@ module ActiveRecord class Scope attr_reader :proxy_scope, :proxy_options, :current_scoped_methods_when_defined - NON_DELEGATE_METHODS = %w(nil? send object_id class extend find size count sum average maximum minimum paginate first last empty? any? respond_to?).to_set + NON_DELEGATE_METHODS = %w(nil? send object_id class extend find size count sum average maximum minimum paginate first last merge empty? any? respond_to?).to_set [].methods.each do |m| unless m =~ /^__/ || NON_DELEGATE_METHODS.include?(m.to_s) delegate m, :to => :proxy_found @@ -159,6 +159,10 @@ module ActiveRecord end end + def merge(other) + Scope.new(self, other.proxy_options) + end + protected def proxy_found @found || load_found diff --git a/activerecord/test/cases/named_scope_test.rb b/activerecord/test/cases/named_scope_test.rb index 6149681..cb5e10b 100644 --- a/activerecord/test/cases/named_scope_test.rb +++ b/activerecord/test/cases/named_scope_test.rb @@ -90,6 +90,18 @@ class NamedScopeTest < ActiveRecord::TestCase assert_equal approved & replied, Topic.approved.replied end + def test_scopes_are_mergeable + approved_scope = Topic.approved + replied_scope = Topic.replied + + assert_equal (approved = Topic.find(:all, :conditions => {:approved => true})), approved_scope + assert_equal (replied = Topic.find(:all, :conditions => 'replies_count > 0')), replied_scope + assert !(approved == replied) + assert !(approved & replied).empty? + + assert_equal approved & replied, approved_scope.merge(replied_scope) + end + def test_procedural_scopes topics_written_before_the_third = Topic.find(:all, :conditions => ['written_on < ?', topics(:third).written_on]) topics_written_before_the_second = Topic.find(:all, :conditions => ['written_on < ?', topics(:second).written_on])