From 5417d1df47309824c4f3203e42caf49b3fc5bd41 Mon Sep 17 00:00:00 2001 From: Andrew White Date: Wed, 31 Mar 2010 07:15:58 +0100 Subject: [PATCH] Fix :delete_all and :nullify dependencies when using nested models --- activerecord/lib/active_record/associations.rb | 22 +++++++------------- activerecord/test/cases/modules_test.rb | 25 +++++++++++++++++++++++- activerecord/test/fixtures/collections.yml | 3 ++ activerecord/test/fixtures/products.yml | 4 +++ activerecord/test/fixtures/variants.yml | 4 +++ activerecord/test/models/company_in_module.rb | 8 +++++++ activerecord/test/models/shop.rb | 12 +++++++++++ activerecord/test/schema/schema.rb | 14 +++++++++++++ 8 files changed, 77 insertions(+), 15 deletions(-) create mode 100644 activerecord/test/fixtures/collections.yml create mode 100644 activerecord/test/fixtures/products.yml create mode 100644 activerecord/test/fixtures/variants.yml create mode 100644 activerecord/test/models/shop.rb diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb index 7406daf..c94c3e1 100755 --- a/activerecord/lib/active_record/associations.rb +++ b/activerecord/lib/active_record/associations.rb @@ -1514,8 +1514,7 @@ module ActiveRecord # before_destroy do |record| # self.class.send(:delete_all_has_many_dependencies, # record, - # "posts", - # Post, + # :posts, # %@...@) # this is a string literal like %(...) # end # end @@ -1523,8 +1522,7 @@ module ActiveRecord before_destroy do |record| self.class.send(:delete_all_has_many_dependencies, record, - "#{reflection.name}", - #{reflection.class_name}, + :#{reflection.name}, %@#{dependent_conditions}@) end CALLBACK @@ -1532,9 +1530,7 @@ module ActiveRecord # before_destroy do |record| # self.class.send(:nullify_has_many_dependencies, # record, - # "posts", - # Post, - # "user_id", + # :posts, # %@...@) # this is a string literal like %(...) # end # end @@ -1542,9 +1538,7 @@ module ActiveRecord before_destroy do |record| self.class.send(:nullify_has_many_dependencies, record, - "#{reflection.name}", - #{reflection.class_name}, - "#{reflection.primary_key_name}", + :#{reflection.name}, %@#{dependent_conditions}@) end CALLBACK @@ -1621,12 +1615,12 @@ module ActiveRecord end end - def delete_all_has_many_dependencies(record, reflection_name, association_class, dependent_conditions) - association_class.delete_all(dependent_conditions) + def delete_all_has_many_dependencies(record, reflection_name, dependent_conditions) + reflections[reflection_name].klass.delete_all(dependent_conditions) end - def nullify_has_many_dependencies(record, reflection_name, association_class, primary_key_name, dependent_conditions) - association_class.update_all("#{primary_key_name} = NULL", dependent_conditions) + def nullify_has_many_dependencies(record, reflection_name, dependent_conditions) + reflections[reflection_name].klass.update_all("#{reflections[reflection_name].primary_key_name} = NULL", dependent_conditions) end mattr_accessor :valid_keys_for_has_many_association diff --git a/activerecord/test/cases/modules_test.rb b/activerecord/test/cases/modules_test.rb index 7209966..8d28398 100644 --- a/activerecord/test/cases/modules_test.rb +++ b/activerecord/test/cases/modules_test.rb @@ -1,8 +1,9 @@ require "cases/helper" require 'models/company_in_module' +require 'models/shop' class ModulesTest < ActiveRecord::TestCase - fixtures :accounts, :companies, :projects, :developers + fixtures :accounts, :companies, :projects, :developers, :collections, :products, :variants def setup # need to make sure Object::Firm and Object::Client are not defined, @@ -110,4 +111,26 @@ class ModulesTest < ActiveRecord::TestCase ActiveRecord::Base.table_name_prefix = '' classes.each(&:reset_table_name) end + + def test_nested_models_should_not_raise_exception_when_using_delete_all_dependency_on_association + old = ActiveRecord::Base.store_full_sti_class + ActiveRecord::Base.store_full_sti_class = true + + collection = Shop::Collection.find(:first) + assert !collection.products.empty?, "Collection should have products" + assert_nothing_raised { collection.destroy } + ensure + ActiveRecord::Base.store_full_sti_class = old + end + + def test_nested_models_should_not_raise_exception_when_using_nullify_dependency_on_association + old = ActiveRecord::Base.store_full_sti_class + ActiveRecord::Base.store_full_sti_class = true + + product = Shop::Product.find(:first) + assert !product.variants.empty?, "Product should have variants" + assert_nothing_raised { product.destroy } + ensure + ActiveRecord::Base.store_full_sti_class = old + end end diff --git a/activerecord/test/fixtures/collections.yml b/activerecord/test/fixtures/collections.yml new file mode 100644 index 0000000..ad0fd26 --- /dev/null +++ b/activerecord/test/fixtures/collections.yml @@ -0,0 +1,3 @@ +collection_1: + id: 1 + name: Collection diff --git a/activerecord/test/fixtures/products.yml b/activerecord/test/fixtures/products.yml new file mode 100644 index 0000000..8a197fb --- /dev/null +++ b/activerecord/test/fixtures/products.yml @@ -0,0 +1,4 @@ +product_1: + id: 1 + collection_id: 1 + name: Product diff --git a/activerecord/test/fixtures/variants.yml b/activerecord/test/fixtures/variants.yml new file mode 100644 index 0000000..06be307 --- /dev/null +++ b/activerecord/test/fixtures/variants.yml @@ -0,0 +1,4 @@ +variant_1: + id: 1 + product_id: 1 + name: Variant diff --git a/activerecord/test/models/company_in_module.rb b/activerecord/test/models/company_in_module.rb index 83d71b6..d31c35e 100644 --- a/activerecord/test/models/company_in_module.rb +++ b/activerecord/test/models/company_in_module.rb @@ -16,6 +16,14 @@ module MyApplication has_one :account, :class_name => 'MyApplication::Billing::Account', :dependent => :destroy end + class DependentFirm < Company + has_many :clients, :foreign_key => "firm_id", :dependent => :delete_all + end + + class NullifyFirm < Company + has_many :clients, :foreign_key => "firm_id", :dependent => :nullify + end + class Client < Company belongs_to :firm, :foreign_key => "client_of" belongs_to :firm_with_other_name, :class_name => "Firm", :foreign_key => "client_of" diff --git a/activerecord/test/models/shop.rb b/activerecord/test/models/shop.rb new file mode 100644 index 0000000..6680ede --- /dev/null +++ b/activerecord/test/models/shop.rb @@ -0,0 +1,12 @@ +module Shop + class Collection < ActiveRecord::Base + has_many :products, :dependent => :nullify + end + + class Product < ActiveRecord::Base + has_many :variants, :dependent => :delete_all + end + + class Variant < ActiveRecord::Base + end +end \ No newline at end of file diff --git a/activerecord/test/schema/schema.rb b/activerecord/test/schema/schema.rb index bec4291..7a0cf55 100644 --- a/activerecord/test/schema/schema.rb +++ b/activerecord/test/schema/schema.rb @@ -99,6 +99,10 @@ ActiveRecord::Schema.define do t.string :name end + create_table :collections, :force => true do |t| + t.string :name + end + create_table :colnametests, :force => true do |t| t.integer :references, :null => false end @@ -394,6 +398,11 @@ ActiveRecord::Schema.define do t.integer :price end + create_table :products, :force => true do |t| + t.references :collection + t.string :name + end + create_table :projects, :force => true do |t| t.string :name t.string :type @@ -499,6 +508,11 @@ ActiveRecord::Schema.define do t.column :looter_type, :string end + create_table :variants, :force => true do |t| + t.references :product + t.string :name + end + create_table :vertices, :force => true do |t| t.column :label, :string end -- 1.6.4.4