aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJon Leighton <j@jonathanleighton.com>2011-11-03 15:07:24 +0000
committerJon Leighton <j@jonathanleighton.com>2011-11-03 15:12:08 +0000
commitd486103570bf680307ba474915efc01862e99403 (patch)
tree8b7a7e64d442fcc73a0f772541ebb4ce5e6fa618
parent567d454d99bd472ef342c047c0038504fa4f960c (diff)
downloadrails-d486103570bf680307ba474915efc01862e99403.tar.gz
rails-d486103570bf680307ba474915efc01862e99403.tar.bz2
rails-d486103570bf680307ba474915efc01862e99403.zip
Fix #3271.
Building the conditions of a nested through association could potentially modify the conditions of the through and/or source association. This is a Bad Thing.
-rw-r--r--activerecord/CHANGELOG7
-rw-r--r--activerecord/lib/active_record/reflection.rb2
-rw-r--r--activerecord/test/cases/reflection_test.rb6
3 files changed, 14 insertions, 1 deletions
diff --git a/activerecord/CHANGELOG b/activerecord/CHANGELOG
index 203b110e98..871cc624ca 100644
--- a/activerecord/CHANGELOG
+++ b/activerecord/CHANGELOG
@@ -39,6 +39,13 @@
*Rails 3.1.2 (unreleased)*
+* Fix bug where building the conditions of a nested through association could potentially
+ modify the conditions of the through and/or source association. If you have experienced
+ bugs with conditions appearing in the wrong queries when using nested through associations,
+ this probably solves your problems. [GH #3271]
+
+ [Jon Leighton]
+
* If a record is removed from a has_many :through, all of the join records relating to that
record should also be removed from the through association's target.
diff --git a/activerecord/lib/active_record/reflection.rb b/activerecord/lib/active_record/reflection.rb
index 5285060288..98f0418d3f 100644
--- a/activerecord/lib/active_record/reflection.rb
+++ b/activerecord/lib/active_record/reflection.rb
@@ -433,7 +433,7 @@ module ActiveRecord
# of relevant reflections, plus any :source_type or polymorphic :as constraints.
def conditions
@conditions ||= begin
- conditions = source_reflection.conditions
+ conditions = source_reflection.conditions.map { |c| c.dup }
# Add to it the conditions from this reflection if necessary.
conditions.first << options[:conditions] if options[:conditions]
diff --git a/activerecord/test/cases/reflection_test.rb b/activerecord/test/cases/reflection_test.rb
index 69e9fc8d61..4d21822cf5 100644
--- a/activerecord/test/cases/reflection_test.rb
+++ b/activerecord/test/cases/reflection_test.rb
@@ -319,6 +319,12 @@ class ReflectionTest < ActiveRecord::TestCase
assert_equal "category_id", Post.reflect_on_association(:categorizations).foreign_key.to_s
end
+ def test_through_reflection_conditions_do_not_modify_other_reflections
+ orig_conds = Post.reflect_on_association(:first_blue_tags_2).conditions.inspect
+ Author.reflect_on_association(:misc_post_first_blue_tags_2).conditions
+ assert_equal orig_conds, Post.reflect_on_association(:first_blue_tags_2).conditions.inspect
+ end
+
private
def assert_reflection(klass, association, options)
assert reflection = klass.reflect_on_association(association)