From 190e04645bf7ae873d922064783a71a88e0060fd Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Thu, 19 May 2005 17:07:56 +0000 Subject: Fixed that :delete_sql in has_and_belongs_to_many associations couldn't access record properties #1299 [Rick Olson] git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@1313 5ecf4fe2-1ee6-0310-87b1-e25e094e27de --- activerecord/CHANGELOG | 2 ++ activerecord/lib/active_record/associations.rb | 2 ++ .../has_and_belongs_to_many_association.rb | 4 ++-- activerecord/test/associations_test.rb | 19 +++++++++++++++++++ activerecord/test/fixtures/project.rb | 1 + 5 files changed, 26 insertions(+), 2 deletions(-) diff --git a/activerecord/CHANGELOG b/activerecord/CHANGELOG index b8328a0575..58a57ea4b1 100644 --- a/activerecord/CHANGELOG +++ b/activerecord/CHANGELOG @@ -1,5 +1,7 @@ *SVN* +* Fixed that :delete_sql in has_and_belongs_to_many associations couldn't access record properties #1299 [Rick Olson] + * Fixed that clone would break when an aggregate had the same name as one of its attributes #1307 [bitsweat] * Changed that destroying an object will only freeze the attributes hash, which keeps the object from having attributes changed (as that wouldn't make sense), but allows for the querying of associations after it has been destroyed. diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb index 4b1de85a90..d0dde54015 100755 --- a/activerecord/lib/active_record/associations.rb +++ b/activerecord/lib/active_record/associations.rb @@ -506,6 +506,8 @@ module ActiveRecord # has_and_belongs_to_many :projects # has_and_belongs_to_many :nations, :class_name => "Country" # has_and_belongs_to_many :categories, :join_table => "prods_cats" + # has_and_belongs_to_many :active_projects, :join_table => 'developers_projects', :delete_sql => + # 'DELETE FROM developers_projects WHERE active=1 AND developer_id = #{id} AND project_id = #{record.id}' def has_and_belongs_to_many(association_id, options = {}) validate_options([ :class_name, :table_name, :foreign_key, :association_foreign_key, :conditions, :join_table, :finder_sql, :delete_sql, :insert_sql, :order, :uniq ], options.keys) diff --git a/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb b/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb index 15211c2223..f827cf3282 100644 --- a/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb +++ b/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb @@ -136,7 +136,7 @@ module ActiveRecord def delete_records(records) if sql = @options[:delete_sql] - records.each { |record| @owner.connection.execute(sql) } + records.each { |record| @owner.connection.execute(interpolate_sql(sql, record)) } else ids = quoted_record_ids(records) sql = "DELETE FROM #{@join_table} WHERE #{@association_class_primary_key_name} = #{@owner.quoted_id} AND #{@association_foreign_key} IN (#{ids})" @@ -145,7 +145,7 @@ module ActiveRecord end def construct_sql - interpolate_sql_options!(@options, :finder_sql, :delete_sql) + interpolate_sql_options!(@options, :finder_sql) if @options[:finder_sql] @finder_sql = @options[:finder_sql] diff --git a/activerecord/test/associations_test.rb b/activerecord/test/associations_test.rb index 3f0fa1c0b6..03fd2b263d 100755 --- a/activerecord/test/associations_test.rb +++ b/activerecord/test/associations_test.rb @@ -859,6 +859,25 @@ class HasAndBelongsToManyAssociationsTest < Test::Unit::TestCase assert_equal 0, david.projects(true).size end + def test_deleting_with_sql + david = Developer.find(1) + active_record = Project.find(1) + active_record.developers.reload + assert_equal 2, active_record.developers_by_sql.size + + active_record.developers_by_sql.delete(david) + assert_equal 1, active_record.developers_by_sql(true).size + end + + def test_deleting_array_with_sql + active_record = Project.find(1) + active_record.developers.reload + assert_equal 2, active_record.developers_by_sql.size + + active_record.developers_by_sql.delete(Developer.find_all) + assert_equal 0, active_record.developers_by_sql(true).size + end + def test_deleting_all david = Developer.find(1) david.projects.reload diff --git a/activerecord/test/fixtures/project.rb b/activerecord/test/fixtures/project.rb index fddea7b61c..89d5c36db8 100644 --- a/activerecord/test/fixtures/project.rb +++ b/activerecord/test/fixtures/project.rb @@ -1,6 +1,7 @@ class Project < ActiveRecord::Base has_and_belongs_to_many :developers, :uniq => true has_and_belongs_to_many :developers_named_david, :class_name => "Developer", :conditions => "name = 'David'", :uniq => true + 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}" end class SpecialProject < Project -- cgit v1.2.3