diff --git a/activerecord/lib/active_record/named_scope.rb b/activerecord/lib/active_record/named_scope.rb index b30ef97..bcd810b 100644 --- a/activerecord/lib/active_record/named_scope.rb +++ b/activerecord/lib/active_record/named_scope.rb @@ -103,7 +103,7 @@ module ActiveRecord attr_reader :proxy_scope, :proxy_options [].methods.each do |m| - unless m =~ /(^__|^nil\?|^send|^object_id$|class|extend|^find$|count|sum|average|maximum|minimum|paginate|first|last|empty\?|respond_to\?)/ + unless m =~ /(^__|^nil\?|^send|^object_id$|class|extend|^find$|count|sum|average|maximum|minimum|paginate|first|last|merge|empty\?|respond_to\?)/ delegate m, :to => :proxy_found end end @@ -144,6 +144,10 @@ module ActiveRecord super || @proxy_scope.respond_to?(method, include_private) 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 be6551c..6aa3529 100644 --- a/activerecord/test/cases/named_scope_test.rb +++ b/activerecord/test/cases/named_scope_test.rb @@ -86,6 +86,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])