diff --git a/actionpack/test/fixtures/replies.yml b/actionpack/test/fixtures/replies.yml index a17d2fc42b3a8de141dccb7b12990e1b67838ca1..2022523eac48d2bfcb22015dc34b1bc38706305d 100644 --- a/actionpack/test/fixtures/replies.yml +++ b/actionpack/test/fixtures/replies.yml @@ -12,4 +12,12 @@ another: developer_id: 1 content: Nuh uh! created_at: <%= 1.hour.ago.to_s(:db) %> - updated_at: nil \ No newline at end of file + updated_at: nil + +best_reply: + id: 3 + topic_id: 3 + developer_id: 2 + content: No one can know + created_at: <%= 5.hours.ago.to_s(:db) %> + updated_at: nil diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index ebc0b7783f990ad48bb0ccc3220de37a60756232..8db3909d9a838dea15c54773b1fd4ab838a8f083 100755 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -2097,7 +2097,11 @@ def with_scope(method_scoping = {}, action = :merge, &block) (hash[method].keys + params.keys).uniq.each do |key| merge = hash[method][key] && params[key] # merge if both scopes have the same key if key == :conditions && merge - hash[method][key] = merge_conditions(params[key], hash[method][key]) + if params[key].is_a?(Hash) && hash[method][key].is_a?(Hash) + hash[method][key] = merge_conditions(hash[method][key].deep_merge(params[key])) + else + hash[method][key] = merge_conditions(params[key], hash[method][key]) + end elsif key == :include && merge hash[method][key] = merge_includes(hash[method][key], params[key]).uniq elsif key == :joins && merge @@ -2107,7 +2111,7 @@ def with_scope(method_scoping = {}, action = :merge, &block) end end else - hash[method] = params.merge(hash[method]) + hash[method] = hash[method].merge(params) end else hash[method] = params diff --git a/activerecord/test/cases/named_scope_test.rb b/activerecord/test/cases/named_scope_test.rb index bab842cf66c67e652c81b373c76a56ad64e8fb88..e1e27fa130dbdb3c911dffcaa63d7d3b7fc7a032 100644 --- a/activerecord/test/cases/named_scope_test.rb +++ b/activerecord/test/cases/named_scope_test.rb @@ -277,6 +277,26 @@ def test_chaining_with_duplicate_joins post = Post.find(1) assert_equal post.comments.size, Post.scoped(:joins => join).scoped(:joins => join, :conditions => "posts.id = #{post.id}").size end + + def test_chanining_should_use_latest_conditions_when_creating + post1 = Topic.rejected.approved.new + assert post1.approved? + + post2 = Topic.approved.rejected.new + assert ! post2.approved? + end + + def test_chanining_should_use_latest_conditions_when_searching + # Normal hash conditions + assert_equal Topic.all(:conditions => {:approved => true}), Topic.rejected.approved.all + assert_equal Topic.all(:conditions => {:approved => false}), Topic.approved.rejected.all + + # Nested hash conditions with same keys + assert_equal [posts(:sti_comments)], Post.with_special_comments.with_very_special_comments.all + + # Nested hash conditions with different keys + assert_equal [posts(:sti_comments)], Post.with_special_comments.with_post(4).all.uniq + end end class DynamicScopeMatchTest < ActiveRecord::TestCase diff --git a/activerecord/test/models/post.rb b/activerecord/test/models/post.rb index e0d8be676a8e0e88f5c7d5060d787635ace0b3c4..388fff8fba175d52ccd53349b0e7260ded270140 100644 --- a/activerecord/test/models/post.rb +++ b/activerecord/test/models/post.rb @@ -17,6 +17,12 @@ def greeting has_one :last_comment, :class_name => 'Comment', :order => 'id desc' + named_scope :with_special_comments, :joins => :comments, :conditions => {:comments => {:type => 'SpecialComment'} } + named_scope :with_very_special_comments, :joins => :comments, :conditions => {:comments => {:type => 'VerySpecialComment'} } + named_scope :with_post, lambda {|post_id| + { :joins => :comments, :conditions => {:comments => {:post_id => post_id} } } + } + has_many :comments, :order => "body" do def find_most_recent find(:first, :order => "id DESC") diff --git a/activerecord/test/models/topic.rb b/activerecord/test/models/topic.rb index 39ca1bf42ad185c3bd003e01fef92550b5c5e17b..08bb24ed03b8dd46d962577104efa2e208d228c1 100644 --- a/activerecord/test/models/topic.rb +++ b/activerecord/test/models/topic.rb @@ -4,6 +4,8 @@ class Topic < ActiveRecord::Base { :conditions => ['written_on < ?', time] } } named_scope :approved, :conditions => {:approved => true} + named_scope :rejected, :conditions => {:approved => false} + named_scope :by_lifo, :conditions => {:author_name => 'lifo'} named_scope :approved_as_hash_condition, :conditions => {:topics => {:approved => true}}