mirror of https://github.com/rails/rails
has_one supports the :dependent => :delete option which skips the typical callback chain and deletes the associated object directly from the database. Closes #5927.
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@4848 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
This commit is contained in:
parent
92f1e26a1c
commit
3704088ebd
|
@ -1,5 +1,7 @@
|
|||
*SVN*
|
||||
|
||||
* has_one supports the :dependent => :delete option which skips the typical callback chain and deletes the associated object directly from the database. #5927 [Chris Mear, Jonathan Viney]
|
||||
|
||||
* Nested subclasses are not prefixed with the parent class' table_name since they should always use the base class' table_name. #5911 [Jonathan Viney]
|
||||
|
||||
* SQLServer: work around bug where some unambiguous date formats are not correctly identified if the session language is set to german. #5894 [Tom Ward, kruth@bfpi]
|
||||
|
|
|
@ -570,8 +570,9 @@ module ActiveRecord
|
|||
# sql fragment, such as "rank = 5".
|
||||
# * <tt>:order</tt> - specify the order from which the associated object will be picked at the top. Specified as
|
||||
# an "ORDER BY" sql fragment, such as "last_name, first_name DESC"
|
||||
# * <tt>:dependent</tt> - if set to :destroy (or true) all the associated objects are destroyed when this object is. Also,
|
||||
# association is assigned.
|
||||
# * <tt>:dependent</tt> - if set to :destroy (or true) the associated object is destroyed when this object is. If set to
|
||||
# :delete the associated object is deleted *without* calling its destroy method. If set to :nullify the associated
|
||||
# object's foreign key is set to NULL. Also, association is assigned.
|
||||
# * <tt>:foreign_key</tt> - specify the foreign key used for the association. By default this is guessed to be the name
|
||||
# of this class in lower-case and "_id" suffixed. So a +Person+ class that makes a has_one association will use "person_id"
|
||||
# as the default foreign_key.
|
||||
|
@ -1020,12 +1021,14 @@ module ActiveRecord
|
|||
case reflection.options[:dependent]
|
||||
when :destroy, true
|
||||
module_eval "before_destroy '#{reflection.name}.destroy unless #{reflection.name}.nil?'"
|
||||
when :delete
|
||||
module_eval "before_destroy '#{reflection.class_name}.delete(#{reflection.name}.id) unless #{reflection.name}.nil?'"
|
||||
when :nullify
|
||||
module_eval "before_destroy '#{reflection.name}.update_attribute(\"#{reflection.primary_key_name}\", nil)'"
|
||||
when nil, false
|
||||
# pass
|
||||
else
|
||||
raise ArgumentError, "The :dependent option expects either :destroy or :nullify."
|
||||
raise ArgumentError, "The :dependent option expects either :destroy, :delete or :nullify."
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -91,6 +91,10 @@ end
|
|||
class HasOneAssociationsTest < Test::Unit::TestCase
|
||||
fixtures :accounts, :companies, :developers, :projects, :developers_projects
|
||||
|
||||
def setup
|
||||
Account.destroyed_account_ids.clear
|
||||
end
|
||||
|
||||
def test_has_one
|
||||
assert_equal companies(:first_firm).account, Account.find(1)
|
||||
assert_equal Account.find(1).credit_limit, companies(:first_firm).account.credit_limit
|
||||
|
@ -168,8 +172,22 @@ class HasOneAssociationsTest < Test::Unit::TestCase
|
|||
num_accounts = Account.count
|
||||
firm = Firm.find(1)
|
||||
assert !firm.account.nil?
|
||||
account_id = firm.account.id
|
||||
assert_equal [], Account.destroyed_account_ids[firm.id]
|
||||
firm.destroy
|
||||
assert_equal num_accounts - 1, Account.count
|
||||
assert_equal [account_id], Account.destroyed_account_ids[firm.id]
|
||||
end
|
||||
|
||||
def test_exclusive_dependence
|
||||
num_accounts = Account.count
|
||||
firm = ExclusivelyDependentFirm.find(9)
|
||||
assert !firm.account.nil?
|
||||
account_id = firm.account.id
|
||||
assert_equal [], Account.destroyed_account_ids[firm.id]
|
||||
firm.destroy
|
||||
assert_equal num_accounts - 1, Account.count
|
||||
assert_equal [], Account.destroyed_account_ids[firm.id]
|
||||
end
|
||||
|
||||
def test_succesful_build_association
|
||||
|
|
|
@ -8,7 +8,7 @@ class CalculationsTest < Test::Unit::TestCase
|
|||
fixtures :companies, :accounts, :topics
|
||||
|
||||
def test_should_sum_field
|
||||
assert_equal 265, Account.sum(:credit_limit)
|
||||
assert_equal 318, Account.sum(:credit_limit)
|
||||
end
|
||||
|
||||
def test_should_average_field
|
||||
|
@ -49,13 +49,13 @@ class CalculationsTest < Test::Unit::TestCase
|
|||
|
||||
def test_should_order_by_grouped_field
|
||||
c = Account.sum(:credit_limit, :group => :firm_id, :order => "firm_id")
|
||||
assert_equal [1, 2, 6], c.keys.compact
|
||||
assert_equal [1, 2, 6, 9], c.keys.compact
|
||||
end
|
||||
|
||||
def test_should_order_by_calculation
|
||||
c = Account.sum(:credit_limit, :group => :firm_id, :order => "sum_credit_limit desc, firm_id")
|
||||
assert_equal [105, 60, 50, 50], c.keys.collect { |k| c[k] }
|
||||
assert_equal [6, 2, 1], c.keys.compact
|
||||
assert_equal [105, 60, 53, 50, 50], c.keys.collect { |k| c[k] }
|
||||
assert_equal [6, 2, 9, 1], c.keys.compact
|
||||
end
|
||||
|
||||
def test_should_limit_calculation
|
||||
|
@ -114,8 +114,8 @@ class CalculationsTest < Test::Unit::TestCase
|
|||
end
|
||||
|
||||
def test_should_calculate_with_invalid_field
|
||||
assert_equal 5, Account.calculate(:count, '*')
|
||||
assert_equal 5, Account.calculate(:count, :all)
|
||||
assert_equal 6, Account.calculate(:count, '*')
|
||||
assert_equal 6, Account.calculate(:count, :all)
|
||||
end
|
||||
|
||||
def test_should_calculate_grouped_with_invalid_field
|
||||
|
@ -193,7 +193,7 @@ class CalculationsTest < Test::Unit::TestCase
|
|||
end
|
||||
|
||||
def test_should_count_selected_field_with_include
|
||||
assert_equal 5, Account.count(:distinct => true, :include => :firm)
|
||||
assert_equal 3, Account.count(:distinct => true, :include => :firm, :select => :credit_limit)
|
||||
assert_equal 6, Account.count(:distinct => true, :include => :firm)
|
||||
assert_equal 4, Account.count(:distinct => true, :include => :firm, :select => :credit_limit)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -454,8 +454,8 @@ class FinderTest < Test::Unit::TestCase
|
|||
end
|
||||
|
||||
def test_select_values
|
||||
assert_equal ["1","2","3","4","5","6","7","8"], Company.connection.select_values("SELECT id FROM companies ORDER BY id").map! { |i| i.to_s }
|
||||
assert_equal ["37signals","Summit","Microsoft", "Flamboyant Software", "Ex Nihilo", "RailsCore", "Leetsoft", "Jadedpixel"], Company.connection.select_values("SELECT name FROM companies ORDER BY id")
|
||||
assert_equal ["1","2","3","4","5","6","7","8","9"], Company.connection.select_values("SELECT id FROM companies ORDER BY id").map! { |i| i.to_s }
|
||||
assert_equal ["37signals","Summit","Microsoft", "Flamboyant Software", "Ex Nihilo", "RailsCore", "Leetsoft", "Jadedpixel", "Odegy"], Company.connection.select_values("SELECT name FROM companies ORDER BY id")
|
||||
end
|
||||
|
||||
protected
|
||||
|
|
|
@ -20,4 +20,9 @@ last_account:
|
|||
rails_core_account_2:
|
||||
id: 5
|
||||
firm_id: 6
|
||||
credit_limit: 55
|
||||
credit_limit: 55
|
||||
|
||||
odegy_account:
|
||||
id: 6
|
||||
firm_id: 9
|
||||
credit_limit: 53
|
||||
|
|
|
@ -47,4 +47,9 @@ leetsoft:
|
|||
jadedpixel:
|
||||
id: 8
|
||||
name: Jadedpixel
|
||||
client_of: 6
|
||||
client_of: 6
|
||||
|
||||
odegy:
|
||||
id: 9
|
||||
name: Odegy
|
||||
type: ExclusivelyDependentFirm
|
||||
|
|
|
@ -42,6 +42,9 @@ class DependentFirm < Company
|
|||
has_many :companies, :foreign_key => 'client_of', :order => "id", :dependent => :nullify
|
||||
end
|
||||
|
||||
class ExclusivelyDependentFirm < Company
|
||||
has_one :account, :foreign_key => "firm_id", :dependent => :delete
|
||||
end
|
||||
|
||||
class Client < Company
|
||||
belongs_to :firm, :foreign_key => "client_of"
|
||||
|
@ -83,6 +86,18 @@ end
|
|||
class Account < ActiveRecord::Base
|
||||
belongs_to :firm
|
||||
|
||||
def self.destroyed_account_ids
|
||||
@destroyed_account_ids ||= Hash.new { |h,k| h[k] = [] }
|
||||
end
|
||||
|
||||
before_destroy do |account|
|
||||
if account.firm
|
||||
Account.destroyed_account_ids[account.firm.id] << account.id
|
||||
end
|
||||
true
|
||||
end
|
||||
|
||||
|
||||
protected
|
||||
def validate
|
||||
errors.add_on_empty "credit_limit"
|
||||
|
|
|
@ -58,7 +58,7 @@ class InheritanceTest < Test::Unit::TestCase
|
|||
end
|
||||
|
||||
def test_inheritance_condition
|
||||
assert_equal 8, Company.count
|
||||
assert_equal 9, Company.count
|
||||
assert_equal 2, Firm.count
|
||||
assert_equal 3, Client.count
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue