Added a second parameter to the build and create method for has_one that controls whether the existing association should be replaced (which means nullifying its foreign key as well). By default this is true, but false can be passed to prevent it.

git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@1392 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
This commit is contained in:
David Heinemeier Hansson
2005-06-06 21:10:59 +00:00
parent 5c2e0fe649
commit 2bdaff4a4e
4 changed files with 53 additions and 3 deletions

View File

@@ -1,5 +1,7 @@
*SVN*
* Added a second parameter to the build and create method for has_one that controls whether the existing association should be replaced (which means nullifying its foreign key as well). By default this is true, but false can be passed to prevent it.
* Using transactional fixtures now causes the data to be loaded only once.
* Added fixture accessor methods that can be used when instantiated fixtures are disabled.

View File

@@ -676,8 +676,9 @@ module ActiveRecord
def association_constructor_method(constructor, association_name, association_class_name, association_class_primary_key_name, options, association_proxy_class)
define_method("#{constructor}_#{association_name}") do |*params|
attributees = params.first unless params.empty?
association = instance_variable_get("@#{association_name}")
attributees = params.first unless params.empty?
replace_existing = params[1].nil? ? true : params[1]
association = instance_variable_get("@#{association_name}")
if association.nil?
association = association_proxy_class.new(self,
@@ -686,7 +687,7 @@ module ActiveRecord
instance_variable_set("@#{association_name}", association)
end
association.send(constructor, attributees)
association.send(constructor, attributees, replace_existing)
end
end

View File

@@ -7,6 +7,24 @@ module ActiveRecord
construct_sql
end
def create(attributes = {}, replace_existing = true)
record = build(attributes, replace_existing)
record.save
record
end
def build(attributes = {}, replace_existing = true)
record = @association_class.new(attributes)
if replace_existing
replace(record, true)
else
record[@association_class_primary_key_name] = @owner.id unless @owner.new_record?
end
record
end
def replace(obj, dont_save = false)
load_target
unless @target.nil?

View File

@@ -97,6 +97,35 @@ class HasOneAssociationsTest < Test::Unit::TestCase
# account is dependent, therefore is destroyed when reference to owner is lost
assert_raises(ActiveRecord::RecordNotFound) { Account.find(old_account_id) }
end
def test_assignment_without_replacement
apple = Firm.create("name" => "Apple")
citibank = Account.create("credit_limit" => 10)
apple.account = citibank
assert_equal apple.id, citibank.firm_id
hsbc = apple.build_account({ :credit_limit => 20}, false)
assert_equal apple.id, hsbc.firm_id
hsbc.save
assert_equal apple.id, citibank.firm_id
nykredit = apple.create_account({ :credit_limit => 30}, false)
assert_equal apple.id, nykredit.firm_id
assert_equal apple.id, citibank.firm_id
assert_equal apple.id, hsbc.firm_id
end
def test_assignment_without_replacement_on_create
apple = Firm.create("name" => "Apple")
citibank = Account.create("credit_limit" => 10)
apple.account = citibank
assert_equal apple.id, citibank.firm_id
hsbc = apple.create_account({ :name => "HSBC", :credit_limit => 10}, false)
assert_equal apple.id, hsbc.firm_id
hsbc.save
assert_equal apple.id, citibank.firm_id
end
def test_dependence
firm = Firm.find(1)