mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Merge pull request #12450 from iantropov/master
Fix bug, when ':dependent => :destroy' violates foreign key constraints Conflicts: activerecord/CHANGELOG.md activerecord/lib/active_record/associations/builder/association.rb activerecord/lib/active_record/associations/builder/has_one.rb
This commit is contained in:
commit
b22edc6488
5 changed files with 59 additions and 5 deletions
|
@ -1,3 +1,10 @@
|
|||
* Move 'dependent: :destroy' handling for 'belongs_to'
|
||||
from 'before_destroy' to 'after_destroy' callback chain
|
||||
|
||||
Fix #12380.
|
||||
|
||||
*Ivan Antropov*
|
||||
|
||||
* Detect in-place modifications on String attributes.
|
||||
|
||||
Before this change user have to mark the attribute as changed to it be persisted
|
||||
|
|
|
@ -85,7 +85,11 @@ module ActiveRecord::Associations::Builder
|
|||
end
|
||||
|
||||
def self.define_callbacks(model, reflection)
|
||||
add_before_destroy_callbacks(model, reflection) if reflection.options[:dependent]
|
||||
if dependent = reflection.options[:dependent]
|
||||
check_dependent_options(dependent)
|
||||
add_destroy_callbacks(model, reflection)
|
||||
end
|
||||
|
||||
Association.extensions.each do |extension|
|
||||
extension.build model, reflection
|
||||
end
|
||||
|
@ -126,11 +130,13 @@ module ActiveRecord::Associations::Builder
|
|||
|
||||
private
|
||||
|
||||
def self.add_before_destroy_callbacks(model, reflection)
|
||||
unless valid_dependent_options.include? reflection.options[:dependent]
|
||||
raise ArgumentError, "The :dependent option must be one of #{valid_dependent_options}, but is :#{reflection.options[:dependent]}"
|
||||
def self.check_dependent_options(dependent)
|
||||
unless valid_dependent_options.include? dependent
|
||||
raise ArgumentError, "The :dependent option must be one of #{valid_dependent_options}, but is :#{dependent}"
|
||||
end
|
||||
end
|
||||
|
||||
def self.add_destroy_callbacks(model, reflection)
|
||||
name = reflection.name
|
||||
model.before_destroy lambda { |o| o.association(name).handle_dependency }
|
||||
end
|
||||
|
|
|
@ -107,5 +107,10 @@ module ActiveRecord::Associations::Builder
|
|||
model.after_touch callback
|
||||
model.after_destroy callback
|
||||
end
|
||||
|
||||
def self.add_destroy_callbacks(model, reflection)
|
||||
name = reflection.name
|
||||
model.after_destroy lambda { |o| o.association(name).handle_dependency }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -16,7 +16,7 @@ module ActiveRecord::Associations::Builder
|
|||
|
||||
private
|
||||
|
||||
def self.add_before_destroy_callbacks(model, reflection)
|
||||
def self.add_destroy_callbacks(model, reflection)
|
||||
super unless reflection.options[:through]
|
||||
end
|
||||
end
|
||||
|
|
|
@ -935,3 +935,39 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
|
|||
assert_equal 1, Column.count
|
||||
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