Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Only save the record once when calling create! on a collection associ…

…ation. Fixes #1360.
  • Loading branch information...
commit 64d7348b98efe7f7ca36551571880210b2451626 1 parent 842043e
@jonleighton jonleighton authored
View
40 activerecord/lib/active_record/associations/collection_association.rb
@@ -104,26 +104,11 @@ def build(attributes = {}, options = {}, &block)
end
def create(attributes = {}, options = {}, &block)
- unless owner.persisted?
- raise ActiveRecord::RecordNotSaved, "You cannot call create unless the parent is saved"
- end
-
- if attributes.is_a?(Array)
- attributes.collect { |attr| create(attr, options, &block) }
- else
- transaction do
- add_to_target(build_record(attributes, options)) do |record|
- yield(record) if block_given?
- insert_record(record)
- end
- end
- end
+ create_record(attributes, options, &block)
end
- def create!(attrs = {}, options = {}, &block)
- record = create(attrs, options, &block)
- Array.wrap(record).each(&:save!)
- record
+ def create!(attributes = {}, options = {}, &block)
+ create_record(attributes, options, true, &block)
end
# Add +records+ to this association. Returns +self+ so method calls may be chained.
@@ -422,8 +407,25 @@ def merge_target_lists(persisted, memory)
persisted + memory
end
+ def create_record(attributes, options, raise = false, &block)
+ unless owner.persisted?
+ raise ActiveRecord::RecordNotSaved, "You cannot call create unless the parent is saved"
+ end
+
+ if attributes.is_a?(Array)
+ attributes.collect { |attr| create_record(attr, options, raise, &block) }
+ else
+ transaction do
+ add_to_target(build_record(attributes, options)) do |record|
+ yield(record) if block_given?
+ insert_record(record, true, raise)
+ end
+ end
+ end
+ end
+
# Do the relevant stuff to insert the given record into the association collection.
- def insert_record(record, validate = true)
+ def insert_record(record, validate = true, raise = false)
raise NotImplementedError
end
View
10 activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb
@@ -9,8 +9,14 @@ def initialize(owner, reflection)
super
end
- def insert_record(record, validate = true)
- return if record.new_record? && !record.save(:validate => validate)
+ def insert_record(record, validate = true, raise = false)
+ if record.new_record?
+ if raise
+ record.save!(:validate => validate)
+ else
+ return unless record.save(:validate => validate)
+ end
+ end
if options[:insert_sql]
owner.connection.insert(interpolate(options[:insert_sql], record))
View
9 activerecord/lib/active_record/associations/has_many_association.rb
@@ -7,9 +7,14 @@ module Associations
# is provided by its child HasManyThroughAssociation.
class HasManyAssociation < CollectionAssociation #:nodoc:
- def insert_record(record, validate = true)
+ def insert_record(record, validate = true, raise = false)
set_owner_attributes(record)
- record.save(:validate => validate)
+
+ if raise
+ record.save!(:validate => validate)
+ else
+ record.save(:validate => validate)
+ end
end
private
View
11 activerecord/lib/active_record/associations/has_many_through_association.rb
@@ -33,9 +33,16 @@ def concat(*records)
super
end
- def insert_record(record, validate = true)
+ def insert_record(record, validate = true, raise = false)
ensure_not_nested
- return if record.new_record? && !record.save(:validate => validate)
+
+ if record.new_record?
+ if raise
+ record.save!(:validate => validate)
+ else
+ return unless record.save(:validate => validate)
+ end
+ end
through_record(record).save!
update_counter(1)
Please sign in to comment.
Something went wrong with that request. Please try again.