diff options
author | Jamis Buck <jamis@37signals.com> | 2005-08-23 11:05:04 +0000 |
---|---|---|
committer | Jamis Buck <jamis@37signals.com> | 2005-08-23 11:05:04 +0000 |
commit | dfe1aeb776ed9a7da8b431c7933c858d155a13c7 (patch) | |
tree | 11593565c25ad674b9fbaf7d9d17e313f0c4198c | |
parent | 211617191ed9e6bc9da1cee1bdd134c9b8c3cdfd (diff) | |
download | rails-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/CHANGELOG | 2 | ||||
-rwxr-xr-x | activerecord/lib/active_record/associations.rb | 8 | ||||
-rwxr-xr-x | activerecord/test/associations_test.rb | 41 | ||||
-rw-r--r-- | activerecord/test/fixtures/db_definitions/db2.sql | 8 | ||||
-rwxr-xr-x | activerecord/test/fixtures/db_definitions/mysql.sql | 10 | ||||
-rw-r--r-- | activerecord/test/fixtures/db_definitions/oci.sql | 9 | ||||
-rw-r--r-- | activerecord/test/fixtures/db_definitions/postgresql.sql | 9 | ||||
-rw-r--r-- | activerecord/test/fixtures/db_definitions/sqlite.sql | 8 | ||||
-rw-r--r-- | activerecord/test/fixtures/db_definitions/sqlserver.sql | 8 | ||||
-rw-r--r-- | activerecord/test/fixtures/order.rb | 4 |
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 |