From b1257d96b7b2482fc7811e5dc12d71c9fa091d10 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Fri, 1 Sep 2006 05:31:56 +0000 Subject: has_many :through conditions are sanitized by the associating class. Closes #5971. git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@4893 5ecf4fe2-1ee6-0310-87b1-e25e094e27de --- activerecord/CHANGELOG | 2 ++ activerecord/lib/active_record/associations/association_proxy.rb | 2 +- .../lib/active_record/associations/has_many_through_association.rb | 4 ++-- activerecord/test/associations_join_model_test.rb | 4 ++++ activerecord/test/associations_test.rb | 6 ++++++ activerecord/test/fixtures/author.rb | 2 ++ activerecord/test/fixtures/project.rb | 1 + activerecord/test/reflection_test.rb | 4 ++-- 8 files changed, 20 insertions(+), 5 deletions(-) diff --git a/activerecord/CHANGELOG b/activerecord/CHANGELOG index 89b06c6df8..da7232902c 100644 --- a/activerecord/CHANGELOG +++ b/activerecord/CHANGELOG @@ -1,5 +1,7 @@ *SVN* +* has_many :through conditions are sanitized by the associating class. #5971 [martin.emde@gmail.com] + * Tighten rescue clauses. #5985 [james@grayproductions.net] * Fix spurious newlines and spaces in AR::Base#to_xml output [Jamis Buck] diff --git a/activerecord/lib/active_record/associations/association_proxy.rb b/activerecord/lib/active_record/associations/association_proxy.rb index 1d313fc537..ac7188d712 100644 --- a/activerecord/lib/active_record/associations/association_proxy.rb +++ b/activerecord/lib/active_record/associations/association_proxy.rb @@ -41,7 +41,7 @@ module ActiveRecord end def conditions - @conditions ||= eval("%(#{@reflection.active_record.send :sanitize_sql, @reflection.options[:conditions]})") if @reflection.options[:conditions] + @conditions ||= eval("%(#{@reflection.klass.send :sanitize_sql, @reflection.options[:conditions]})") if @reflection.options[:conditions] end alias :sql_conditions :conditions diff --git a/activerecord/lib/active_record/associations/has_many_through_association.rb b/activerecord/lib/active_record/associations/has_many_through_association.rb index 1962dc77ff..3888bc62ba 100644 --- a/activerecord/lib/active_record/associations/has_many_through_association.rb +++ b/activerecord/lib/active_record/associations/has_many_through_association.rb @@ -207,8 +207,8 @@ module ActiveRecord def conditions @conditions ||= [ - (interpolate_sql(@reflection.active_record.send(:sanitize_sql, @reflection.options[:conditions])) if @reflection.options[:conditions]), - (interpolate_sql(@reflection.active_record.send(:sanitize_sql, @reflection.through_reflection.options[:conditions])) if @reflection.through_reflection.options[:conditions]) + (interpolate_sql(@reflection.klass.send(:sanitize_sql, @reflection.options[:conditions])) if @reflection.options[:conditions]), + (interpolate_sql(@reflection.through_reflection.klass.send(:sanitize_sql, @reflection.through_reflection.options[:conditions])) if @reflection.through_reflection.options[:conditions]) ].compact.collect { |condition| "(#{condition})" }.join(' AND ') unless (!@reflection.options[:conditions] && !@reflection.through_reflection.options[:conditions]) end diff --git a/activerecord/test/associations_join_model_test.rb b/activerecord/test/associations_join_model_test.rb index 77908d4540..fb8df9c21c 100644 --- a/activerecord/test/associations_join_model_test.rb +++ b/activerecord/test/associations_join_model_test.rb @@ -246,6 +246,10 @@ class AssociationsJoinModelTest < Test::Unit::TestCase def test_has_many_find_first assert_equal categories(:general), authors(:david).categories.find(:first) end + + def test_has_many_with_hash_conditions + assert_equal categories(:general), authors(:david).categories_like_general.find(:first) + end def test_has_many_find_conditions assert_equal categories(:general), authors(:david).categories.find(:first, :conditions => "categories.name = 'General'") diff --git a/activerecord/test/associations_test.rb b/activerecord/test/associations_test.rb index 100b30f126..ede0e399c0 100755 --- a/activerecord/test/associations_test.rb +++ b/activerecord/test/associations_test.rb @@ -410,6 +410,10 @@ class HasManyAssociationsTest < Test::Unit::TestCase assert_equal "Microsoft", Firm.find(:first).clients_like_ms.first.name end + def test_finding_with_condition_hash + assert_equal "Microsoft", Firm.find(:first).clients_like_ms_with_hash_conditions.first.name + end + def test_finding_using_sql firm = Firm.find(:first) first_client = firm.clients_using_sql.first @@ -1546,8 +1550,10 @@ class HasAndBelongsToManyAssociationsTest < Test::Unit::TestCase def test_associations_with_conditions assert_equal 3, projects(:active_record).developers.size assert_equal 1, projects(:active_record).developers_named_david.size + assert_equal 1, projects(:active_record).developers_named_david_with_hash_conditions.size assert_equal developers(:david), projects(:active_record).developers_named_david.find(developers(:david).id) + assert_equal developers(:david), projects(:active_record).developers_named_david_with_hash_conditions.find(developers(:david).id) assert_equal developers(:david), projects(:active_record).salaried_developers.find(developers(:david).id) projects(:active_record).developers_named_david.clear diff --git a/activerecord/test/fixtures/author.rb b/activerecord/test/fixtures/author.rb index a9102a269a..1c49b90fe5 100644 --- a/activerecord/test/fixtures/author.rb +++ b/activerecord/test/fixtures/author.rb @@ -37,6 +37,8 @@ class Author < ActiveRecord::Base has_many :categorizations has_many :categories, :through => :categorizations + has_many :categories_like_general, :through => :categorizations, :source => :category, :class_name => 'Category', :conditions => { :name => 'General' } + has_many :categorized_posts, :through => :categorizations, :source => :post has_many :unique_categorized_posts, :through => :categorizations, :source => :post, :uniq => true diff --git a/activerecord/test/fixtures/project.rb b/activerecord/test/fixtures/project.rb index 4d4e0e127a..2079dc9b58 100644 --- a/activerecord/test/fixtures/project.rb +++ b/activerecord/test/fixtures/project.rb @@ -3,6 +3,7 @@ class Project < ActiveRecord::Base has_and_belongs_to_many :non_unique_developers, :order => 'developers.name desc, developers.id desc', :class_name => 'Developer' has_and_belongs_to_many :limited_developers, :class_name => "Developer", :limit => 1 has_and_belongs_to_many :developers_named_david, :class_name => "Developer", :conditions => "name = 'David'", :uniq => true + has_and_belongs_to_many :developers_named_david_with_hash_conditions, :class_name => "Developer", :conditions => { :name => 'David' }, :uniq => true has_and_belongs_to_many :salaried_developers, :class_name => "Developer", :conditions => "salary > 0" has_and_belongs_to_many :developers_with_finder_sql, :class_name => "Developer", :finder_sql => 'SELECT t.*, j.* FROM developers_projects j, developers t WHERE t.id = j.developer_id AND j.project_id = #{id}' has_and_belongs_to_many :developers_by_sql, :class_name => "Developer", :delete_sql => "DELETE FROM developers_projects WHERE project_id = \#{id} AND developer_id = \#{record.id}" diff --git a/activerecord/test/reflection_test.rb b/activerecord/test/reflection_test.rb index 907d02193f..86fb083348 100644 --- a/activerecord/test/reflection_test.rb +++ b/activerecord/test/reflection_test.rb @@ -143,8 +143,8 @@ class ReflectionTest < Test::Unit::TestCase end def test_reflection_of_all_associations - assert_equal 14, Firm.reflect_on_all_associations.size - assert_equal 12, Firm.reflect_on_all_associations(:has_many).size + assert_equal 15, Firm.reflect_on_all_associations.size + assert_equal 13, Firm.reflect_on_all_associations(:has_many).size assert_equal 2, Firm.reflect_on_all_associations(:has_one).size assert_equal 0, Firm.reflect_on_all_associations(:belongs_to).size end -- cgit v1.2.3