aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJamis Buck <jamis@37signals.com>2005-08-23 11:05:04 +0000
committerJamis Buck <jamis@37signals.com>2005-08-23 11:05:04 +0000
commitdfe1aeb776ed9a7da8b431c7933c858d155a13c7 (patch)
tree11593565c25ad674b9fbaf7d9d17e313f0c4198c
parent211617191ed9e6bc9da1cee1bdd134c9b8c3cdfd (diff)
downloadrails-dfe1aeb776ed9a7da8b431c7933c858d155a13c7.tar.gz
rails-dfe1aeb776ed9a7da8b431c7933c858d155a13c7.tar.bz2
rails-dfe1aeb776ed9a7da8b431c7933c858d155a13c7.zip
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
-rw-r--r--activerecord/CHANGELOG2
-rwxr-xr-xactiverecord/lib/active_record/associations.rb8
-rwxr-xr-xactiverecord/test/associations_test.rb41
-rw-r--r--activerecord/test/fixtures/db_definitions/db2.sql8
-rwxr-xr-xactiverecord/test/fixtures/db_definitions/mysql.sql10
-rw-r--r--activerecord/test/fixtures/db_definitions/oci.sql9
-rw-r--r--activerecord/test/fixtures/db_definitions/postgresql.sql9
-rw-r--r--activerecord/test/fixtures/db_definitions/sqlite.sql8
-rw-r--r--activerecord/test/fixtures/db_definitions/sqlserver.sql8
-rw-r--r--activerecord/test/fixtures/order.rb4
10 files changed, 103 insertions, 4 deletions
diff --git a/activerecord/CHANGELOG b/activerecord/CHANGELOG
index beb419b62c..21decee967 100644
--- a/activerecord/CHANGELOG
+++ b/activerecord/CHANGELOG
@@ -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]
diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb
index ffb0d5679b..d0db4469e2 100755
--- a/activerecord/lib/active_record/associations.rb
+++ b/activerecord/lib/active_record/associations.rb
@@ -445,10 +445,12 @@ module ActiveRecord
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
diff --git a/activerecord/test/associations_test.rb b/activerecord/test/associations_test.rb
index f922359d0a..afb69c0b4b 100755
--- a/activerecord/test/associations_test.rb
+++ b/activerecord/test/associations_test.rb
@@ -5,6 +5,8 @@ require 'fixtures/company'
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 @@ class BelongsToAssociationsTest < Test::Unit::TestCase
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
diff --git a/activerecord/test/fixtures/db_definitions/db2.sql b/activerecord/test/fixtures/db_definitions/db2.sql
index 5977dc4bb2..9c41f7eede 100644
--- a/activerecord/test/fixtures/db_definitions/db2.sql
+++ b/activerecord/test/fixtures/db_definitions/db2.sql
@@ -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,
diff --git a/activerecord/test/fixtures/db_definitions/mysql.sql b/activerecord/test/fixtures/db_definitions/mysql.sql
index 1400f1608b..d581ee3ae8 100755
--- a/activerecord/test/fixtures/db_definitions/mysql.sql
+++ b/activerecord/test/fixtures/db_definitions/mysql.sql
@@ -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; \ No newline at end of file
diff --git a/activerecord/test/fixtures/db_definitions/oci.sql b/activerecord/test/fixtures/db_definitions/oci.sql
index 8abdc0e6ae..f6e958d7c2 100644
--- a/activerecord/test/fixtures/db_definitions/oci.sql
+++ b/activerecord/test/fixtures/db_definitions/oci.sql
@@ -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,
diff --git a/activerecord/test/fixtures/db_definitions/postgresql.sql b/activerecord/test/fixtures/db_definitions/postgresql.sql
index 9d2e50132a..21ca82a4ab 100644
--- a/activerecord/test/fixtures/db_definitions/postgresql.sql
+++ b/activerecord/test/fixtures/db_definitions/postgresql.sql
@@ -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,
diff --git a/activerecord/test/fixtures/db_definitions/sqlite.sql b/activerecord/test/fixtures/db_definitions/sqlite.sql
index 2ffe91324c..d5879c31d8 100644
--- a/activerecord/test/fixtures/db_definitions/sqlite.sql
+++ b/activerecord/test/fixtures/db_definitions/sqlite.sql
@@ -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,
diff --git a/activerecord/test/fixtures/db_definitions/sqlserver.sql b/activerecord/test/fixtures/db_definitions/sqlserver.sql
index e5123ccef0..76ec7aabf3 100644
--- a/activerecord/test/fixtures/db_definitions/sqlserver.sql
+++ b/activerecord/test/fixtures/db_definitions/sqlserver.sql
@@ -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,
diff --git a/activerecord/test/fixtures/order.rb b/activerecord/test/fixtures/order.rb
new file mode 100644
index 0000000000..ba114f22c6
--- /dev/null
+++ b/activerecord/test/fixtures/order.rb
@@ -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