Saving a record with two unsaved belongs_to associations pointing to the same object fails #2023 [Tobias Luetke]

git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@2040 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
This commit is contained in:
Jamis Buck 2005-08-23 11:05:04 +00:00
parent 211617191e
commit dfe1aeb776
10 changed files with 103 additions and 4 deletions

@ -1,5 +1,7 @@
*SVN*
* Saving a record with two unsaved belongs_to associations pointing to the same object fails #2023 [Tobias Luetke]
* Make destroy return self #1913 [sebastian.kanthak@muehlheim.de]
* Fix typo in validations documentation #1938 [court3nay]

@ -445,10 +445,12 @@ def belongs_to(association_id, options = {})
module_eval do
before_save <<-EOF
association = instance_variable_get("@#{association_name}")
if not association.nil? and association.new_record?
association.save(true)
if not association.nil?
if association.new_record?
association.save(true)
association.send(:construct_sql)
end
self["#{association_class_primary_key_name}"] = association.id
association.send(:construct_sql)
end
EOF
end

@ -5,6 +5,8 @@
require 'fixtures/topic'
require 'fixtures/reply'
require 'fixtures/computer'
require 'fixtures/customer'
require 'fixtures/order'
# Can't declare new classes in test case methods, so tests before that
bad_collection_keys = false
@ -770,6 +772,45 @@ def xtest_counter_cache
apple.clients.to_s
assert_equal 1, apple.clients.size, "Should not use the cached number, but go to the database"
end
def test_store_two_association_with_one_save
num_orders = Order.count
num_customers = Customer.count
order = Order.new
customer1 = order.billing = Customer.new
customer2 = order.shipping = Customer.new
assert order.save
assert_equal customer1, order.billing
assert_equal customer2, order.shipping
order.reload
assert_equal customer1, order.billing
assert_equal customer2, order.shipping
assert_equal num_orders +1, Order.count
assert_equal num_customers +2, Customer.count
end
def test_store_association_in_two_relations_with_one_save
num_orders = Order.count
num_customers = Customer.count
order = Order.new
customer = order.billing = order.shipping = Customer.new
assert order.save
assert_equal customer, order.billing
assert_equal customer, order.shipping
order.reload
assert_equal customer, order.billing
assert_equal customer, order.shipping
assert_equal num_orders +1, Order.count
assert_equal num_customers +1, Customer.count
end
end

@ -55,6 +55,14 @@ CREATE TABLE developers_projects (
access_level smallint default 1
);
CREATE TABLE orders (
id int generated by default as identity (start with +10000),
name varchar(100) default NULL,
billing_customer_id int default NULL,
shipping_customer_id int default NULL,
PRIMARY KEY (id)
);
CREATE TABLE customers (
id int generated by default as identity (start with +10000),
name varchar(100) default NULL,

@ -56,6 +56,14 @@ CREATE TABLE `developers_projects` (
`access_level` smallint default 1
) TYPE=InnoDB;
CREATE TABLE `orders` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(100) default NULL,
`billing_customer_id` int(11) default NULL,
`shipping_customer_id` int(11) default NULL,
PRIMARY KEY (`id`)
) TYPE=InnoDB;
CREATE TABLE `customers` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(100) default NULL,
@ -182,4 +190,4 @@ CREATE TABLE `fk_test_has_fk` (
`fk_id` INTEGER NOT NULL,
FOREIGN KEY (`fk_id`) REFERENCES `fk_test_has_pk`(`id`)
) TYPE=InnoDB;
) TYPE=InnoDB;

@ -89,6 +89,15 @@ create table developers_projects (
);
create sequence developers_projects_seq minvalue 10000;
create table orders (
id integer not null,
name varchar(100) default null,
billing_customer_id integer default null,
shipping_customer_id integer default null,
primary key (id)
);
create sequence orders_seq minvalue 10000;
create table customers (
id integer not null,
name varchar(100) default null,

@ -72,6 +72,15 @@ CREATE TABLE customers (
);
SELECT setval('customers_id_seq', 100);
CREATE TABLE orders (
id serial,
name character varying,
billing_customer_id integer,
shipping_customer_id integer,
PRIMARY KEY (id)
);
SELECT setval('orders_id_seq', 100);
CREATE TABLE movies (
movieid serial,
name text,

@ -51,6 +51,14 @@ CREATE TABLE 'developers_projects' (
'access_level' INTEGER DEFAULT 1
);
CREATE TABLE 'orders' (
'id' INTEGER PRIMARY KEY NOT NULL,
'name' VARCHAR(255) DEFAULT NULL,
'billing_customer_id' INTEGER DEFAULT NULL,
'shipping_customer_id' INTEGER DEFAULT NULL
);
CREATE TABLE 'customers' (
'id' INTEGER PRIMARY KEY NOT NULL,
'name' VARCHAR(255) DEFAULT NULL,

@ -50,6 +50,14 @@ CREATE TABLE developers_projects (
access_level int default 1
);
CREATE TABLE orders (
id int NOT NULL IDENTITY(1, 1) PRIMARY KEY,
name varchar(100) default NULL,
billing_customer_id int default NULL,
shipping_customer_id int default NULL
);
CREATE TABLE customers (
id int NOT NULL IDENTITY(1, 1) PRIMARY KEY,
name varchar(100) default NULL,

4
activerecord/test/fixtures/order.rb vendored Normal file

@ -0,0 +1,4 @@
class Order < ActiveRecord::Base
belongs_to :billing, :class_name => 'Customer', :foreign_key => 'billing_customer_id'
belongs_to :shipping, :class_name => 'Customer', :foreign_key => 'shipping_customer_id'
end