aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
authorAndrew White <andyw@pixeltrix.co.uk>2011-05-17 20:37:11 +0100
committerAndrew White <andyw@pixeltrix.co.uk>2011-05-17 20:43:30 +0100
commit42f1ad68655be08a0ff7e5a261d1ad21d3fc90a5 (patch)
treeb38279cb013fdce55ff81329a44aa55b29460a7c /activerecord
parentb81f77e2e23d3792cd95f7b86158875a3a6a0dc2 (diff)
downloadrails-42f1ad68655be08a0ff7e5a261d1ad21d3fc90a5.tar.gz
rails-42f1ad68655be08a0ff7e5a261d1ad21d3fc90a5.tar.bz2
rails-42f1ad68655be08a0ff7e5a261d1ad21d3fc90a5.zip
Pass the attribute and option hashes to build_association
The build_association method was added as an API for plugins to hook into in 1398db0. This commit restores this API and the ability to override class.new to return a subclass based on a virtual attribute in the attributes hash.
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/lib/active_record/associations/collection_association.rb8
-rw-r--r--activerecord/lib/active_record/associations/singular_association.rb12
-rw-r--r--activerecord/test/cases/associations/has_many_associations_test.rb13
-rw-r--r--activerecord/test/cases/associations/has_one_associations_test.rb16
-rw-r--r--activerecord/test/models/bulb.rb13
5 files changed, 54 insertions, 8 deletions
diff --git a/activerecord/lib/active_record/associations/collection_association.rb b/activerecord/lib/active_record/associations/collection_association.rb
index 525ac65722..902ad8cb64 100644
--- a/activerecord/lib/active_record/associations/collection_association.rb
+++ b/activerecord/lib/active_record/associations/collection_association.rb
@@ -423,9 +423,13 @@ module ActiveRecord
raise NotImplementedError
end
+ def create_scope
+ scoped.scope_for_create.stringify_keys
+ end
+
def build_record(attributes, options)
- record = reflection.build_association
- record.assign_attributes(scoped.scope_for_create, :without_protection => true)
+ record = reflection.build_association(attributes, options)
+ record.assign_attributes(create_scope.except(*record.changed), :without_protection => true)
record.assign_attributes(attributes, options)
record
end
diff --git a/activerecord/lib/active_record/associations/singular_association.rb b/activerecord/lib/active_record/associations/singular_association.rb
index 877ddf3ee1..44dbe984d4 100644
--- a/activerecord/lib/active_record/associations/singular_association.rb
+++ b/activerecord/lib/active_record/associations/singular_association.rb
@@ -26,18 +26,18 @@ module ActiveRecord
end
def build(attributes = {}, options = {})
- record = reflection.build_association
- record.assign_attributes(
- scoped.scope_for_create.except(klass.primary_key),
- :without_protection => true
- )
- record.assign_attributes(attributes, options)
+ record = reflection.build_association(attributes, options)
+ record.assign_attributes(create_scope.except(*record.changed), :without_protection => true)
set_new_record(record)
record
end
private
+ def create_scope
+ scoped.scope_for_create.stringify_keys.except(klass.primary_key)
+ end
+
def find_target
scoped.first.tap { |record| set_inverse_instance(record) }
end
diff --git a/activerecord/test/cases/associations/has_many_associations_test.rb b/activerecord/test/cases/associations/has_many_associations_test.rb
index 0e33fa9c8e..522ac56d82 100644
--- a/activerecord/test/cases/associations/has_many_associations_test.rb
+++ b/activerecord/test/cases/associations/has_many_associations_test.rb
@@ -1455,4 +1455,17 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
assert_equal "RED!", car.bulbs.to_a.first.color
end
+
+ def test_new_is_called_with_attributes_and_options
+ car = Car.create(:name => 'honda')
+
+ bulb = car.bulbs.build
+ assert_equal Bulb, bulb.class
+
+ bulb = car.bulbs.build(:bulb_type => :custom)
+ assert_equal Bulb, bulb.class
+
+ bulb = car.bulbs.build({ :bulb_type => :custom }, :as => :admin)
+ assert_equal CustomBulb, bulb.class
+ end
end
diff --git a/activerecord/test/cases/associations/has_one_associations_test.rb b/activerecord/test/cases/associations/has_one_associations_test.rb
index 356a4a7a09..38e622f90f 100644
--- a/activerecord/test/cases/associations/has_one_associations_test.rb
+++ b/activerecord/test/cases/associations/has_one_associations_test.rb
@@ -410,4 +410,20 @@ class HasOneAssociationsTest < ActiveRecord::TestCase
bulb = car.create_frickinawesome_bulb(:frickinawesome => false)
assert_equal true, bulb.frickinawesome?
end
+
+ def test_new_is_called_with_attributes_and_options
+ car = Car.create(:name => 'honda')
+
+ bulb = car.build_bulb
+ assert_equal Bulb, bulb.class
+
+ bulb = car.build_bulb
+ assert_equal Bulb, bulb.class
+
+ bulb = car.build_bulb(:bulb_type => :custom)
+ assert_equal Bulb, bulb.class
+
+ bulb = car.build_bulb({ :bulb_type => :custom }, :as => :admin)
+ assert_equal CustomBulb, bulb.class
+ end
end
diff --git a/activerecord/test/models/bulb.rb b/activerecord/test/models/bulb.rb
index 7d90963720..0dcc8d5970 100644
--- a/activerecord/test/models/bulb.rb
+++ b/activerecord/test/models/bulb.rb
@@ -15,4 +15,17 @@ class Bulb < ActiveRecord::Base
self[:color] = color.upcase + "!"
end
+ def self.new(attributes = {}, options = {}, &block)
+ bulb_type = (attributes || {}).delete(:bulb_type)
+
+ if options && options[:as] == :admin && bulb_type.present?
+ bulb_class = "#{bulb_type.to_s.camelize}Bulb".constantize
+ bulb_class.new(attributes, options, &block)
+ else
+ super
+ end
+ end
end
+
+class CustomBulb < Bulb
+end \ No newline at end of file