aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/associations/association_collection.rb
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord/lib/active_record/associations/association_collection.rb')
-rw-r--r--activerecord/lib/active_record/associations/association_collection.rb54
1 files changed, 27 insertions, 27 deletions
diff --git a/activerecord/lib/active_record/associations/association_collection.rb b/activerecord/lib/active_record/associations/association_collection.rb
index 888ebdf7af..ca350f51c9 100644
--- a/activerecord/lib/active_record/associations/association_collection.rb
+++ b/activerecord/lib/active_record/associations/association_collection.rb
@@ -56,31 +56,15 @@ module ActiveRecord
end
def build(attributes = {}, &block)
- if attributes.is_a?(Array)
- attributes.collect { |attr| build(attr, &block) }
- else
- add_to_target(build_record(attributes)) do |record|
- yield(record) if block_given?
- set_owner_attributes(record)
- end
- end
+ build_or_create(attributes, :build, &block)
end
- def create(attributes = {})
+ def create(attributes = {}, &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) }
- else
- transaction do
- add_to_target(build_record(attributes)) do |record|
- yield(record) if block_given?
- insert_record(record)
- end
- end
- end
+ build_or_create(attributes, :create, &block)
end
def create!(attrs = {}, &block)
@@ -354,17 +338,20 @@ module ActiveRecord
end
def add_to_target(record)
- callback(:before_add, record)
- yield(record) if block_given?
+ transaction do
+ callback(:before_add, record)
+ yield(record) if block_given?
- if @reflection.options[:uniq] && index = @target.index(record)
- @target[index] = record
- else
- @target << record
+ if @reflection.options[:uniq] && index = @target.index(record)
+ @target[index] = record
+ else
+ @target << record
+ end
+
+ callback(:after_add, record)
+ set_inverse_instance(record)
end
- callback(:after_add, record)
- set_inverse_instance(record)
record
end
@@ -425,6 +412,19 @@ module ActiveRecord
end + existing
end
+ def build_or_create(attributes, method)
+ records = Array.wrap(attributes).map do |attrs|
+ record = build_record(attrs)
+
+ add_to_target(record) do
+ yield(record) if block_given?
+ insert_record(record) if method == :create
+ end
+ end
+
+ attributes.is_a?(Array) ? records : records.first
+ end
+
# Do the relevant stuff to insert the given record into the association collection.
def insert_record(record, validate = true)
raise NotImplementedError