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
This commit is contained in:
David Heinemeier Hansson 2005-05-19 17:07:56 +00:00
parent b3fcf2fa3c
commit 190e04645b
5 changed files with 26 additions and 2 deletions

View File

@ -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.

View File

@ -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)

View File

@ -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]

View File

@ -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

View File

@ -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