mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Fix bug, when ':dependent => :destroy' option violates foreign key constraints, issue #12380
This commit is contained in:
parent
fa915461bc
commit
87d1aba3cb
5 changed files with 61 additions and 9 deletions
|
@ -1,3 +1,10 @@
|
|||
* Move 'dependent: :destroy' handling for 'belongs_to'
|
||||
from 'before_destroy' to 'after_destroy' callback chain
|
||||
|
||||
Fix #12380.
|
||||
|
||||
*Ivan Antropov*
|
||||
|
||||
* Fixed `ActiveRecord::Associations::CollectionAssociation#find`
|
||||
when using `has_many` association with `:inverse_of` and finding an array of one element,
|
||||
it should return an array of one element too.
|
||||
|
|
|
@ -69,7 +69,10 @@ module ActiveRecord::Associations::Builder
|
|||
end
|
||||
|
||||
def define_callbacks(model, reflection)
|
||||
add_before_destroy_callbacks(model, name) if options[:dependent]
|
||||
if options[:dependent]
|
||||
check_dependent_options
|
||||
add_destroy_callbacks(model, name)
|
||||
end
|
||||
Association.extensions.each do |extension|
|
||||
extension.build model, reflection
|
||||
end
|
||||
|
@ -110,12 +113,14 @@ module ActiveRecord::Associations::Builder
|
|||
|
||||
private
|
||||
|
||||
def add_before_destroy_callbacks(model, name)
|
||||
unless valid_dependent_options.include? options[:dependent]
|
||||
raise ArgumentError, "The :dependent option must be one of #{valid_dependent_options}, but is :#{options[:dependent]}"
|
||||
def check_dependent_options
|
||||
unless valid_dependent_options.include? options[:dependent]
|
||||
raise ArgumentError, "The :dependent option must be one of #{valid_dependent_options}, but is :#{options[:dependent]}"
|
||||
end
|
||||
end
|
||||
|
||||
model.before_destroy lambda { |o| o.association(name).handle_dependency }
|
||||
end
|
||||
def add_destroy_callbacks(model, name)
|
||||
model.before_destroy lambda { |o| o.association(name).handle_dependency }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -133,5 +133,9 @@ module ActiveRecord::Associations::Builder
|
|||
model.after_touch callback
|
||||
model.after_destroy callback
|
||||
end
|
||||
|
||||
def add_destroy_callbacks(model, name)
|
||||
model.after_destroy lambda { |o| o.association(name).handle_dependency }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -20,8 +20,8 @@ module ActiveRecord::Associations::Builder
|
|||
|
||||
private
|
||||
|
||||
def add_before_destroy_callbacks(model, name)
|
||||
super unless options[:through]
|
||||
end
|
||||
def add_destroy_callbacks(model, name)
|
||||
super unless options[:through]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -831,3 +831,39 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
|
|||
assert_equal post.author_id, author2.id
|
||||
end
|
||||
end
|
||||
|
||||
class BelongsToWithForeignKeyTest < ActiveRecord::TestCase
|
||||
def setup
|
||||
ActiveRecord::Schema.define do
|
||||
drop_table :authors, if_exists: true
|
||||
drop_table :author_addresses, if_exists: true
|
||||
|
||||
create_table :author_addresses do |t|
|
||||
end
|
||||
|
||||
exec_query <<-eos
|
||||
create table authors(
|
||||
id int,
|
||||
author_address_id int,
|
||||
name varchar(255),
|
||||
PRIMARY KEY (id),
|
||||
FOREIGN KEY (author_address_id) REFERENCES author_addresses(id)
|
||||
);
|
||||
eos
|
||||
end
|
||||
end
|
||||
|
||||
def teardown
|
||||
ActiveRecord::Schema.define do
|
||||
drop_table :authors, if_exists: true
|
||||
drop_table :author_addresses, if_exists: true
|
||||
end
|
||||
end
|
||||
|
||||
def test_destroy_linked_models
|
||||
address = AuthorAddress.create!
|
||||
author = Author.create! id: 1, name: "Author", author_address_id: address.id
|
||||
|
||||
author.destroy!
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue