aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/associations
diff options
context:
space:
mode:
authorDavid Heinemeier Hansson <david@loudthinking.com>2005-01-24 11:39:23 +0000
committerDavid Heinemeier Hansson <david@loudthinking.com>2005-01-24 11:39:23 +0000
commitb29c01ea8914422c6f7e0bb5c65d3b8610dc54d1 (patch)
tree42d4e9154911756823bf1197708177b58dd5fd31 /activerecord/lib/active_record/associations
parent1d618455870cac504256cd762cd0787c739dfe1f (diff)
downloadrails-b29c01ea8914422c6f7e0bb5c65d3b8610dc54d1.tar.gz
rails-b29c01ea8914422c6f7e0bb5c65d3b8610dc54d1.tar.bz2
rails-b29c01ea8914422c6f7e0bb5c65d3b8610dc54d1.zip
Added that has_and_belongs_to_many associations with additional attributes also can be created between unsaved objects and only committed to the database when Base#save is called on the associator #524 [Eric Anderson]
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@484 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
Diffstat (limited to 'activerecord/lib/active_record/associations')
-rw-r--r--activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb37
1 files changed, 24 insertions, 13 deletions
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 83b87547ee..77d2fb9cde 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
@@ -81,8 +81,8 @@ module ActiveRecord
def push_with_attributes(record, join_attributes = {})
raise_on_type_mismatch(record)
- insert_record_with_join_attributes(record, join_attributes)
- join_attributes.each { |key, value| record.send(:write_attribute, key, value) }
+ join_attributes.each { |key, value| record[key.to_s] = value }
+ insert_record(record) unless @owner.new_record?
@target << record
self
end
@@ -105,22 +105,33 @@ module ActiveRecord
def insert_record(record)
return false unless record.save
+
if @options[:insert_sql]
@owner.connection.execute(interpolate_sql(@options[:insert_sql], record))
else
- sql = "INSERT INTO #{@join_table} (#{@association_class_primary_key_name}, #{@association_foreign_key}) " +
- "VALUES (#{@owner.quoted_id},#{record.quoted_id})"
+ columns = @owner.connection.columns(@join_table, "#{@join_table} Columns")
+
+ attributes = columns.inject({}) do |attributes, column|
+ case column.name
+ when @association_class_primary_key_name
+ attributes[column.name] = @owner.quoted_id
+ when @association_foreign_key
+ attributes[column.name] = record.quoted_id
+ else
+ value = record[column.name]
+ attributes[column.name] = value unless value.nil?
+ end
+ attributes
+ end
+
+ sql =
+ "INSERT INTO #{@join_table} (#{@owner.send(:quoted_column_names, attributes).join(', ')}) " +
+ "VALUES (#{attributes.values.collect { |value| @owner.send(:quote, value) }.join(', ')})"
+
@owner.connection.execute(sql)
end
- true
- end
-
- def insert_record_with_join_attributes(record, join_attributes)
- attributes = { @association_class_primary_key_name => @owner.id, @association_foreign_key => record.id }.update(join_attributes)
- sql =
- "INSERT INTO #{@join_table} (#{@owner.send(:quoted_column_names, attributes).join(', ')}) " +
- "VALUES (#{attributes.values.collect { |value| @owner.send(:quote, value) }.join(', ')})"
- @owner.connection.execute(sql)
+
+ return true
end
def delete_records(records)