mirror of https://github.com/rails/rails
Add support for nullifying CPK has_one associations
Composite primary key records need to conditionally unset multiple column attributes from the associated record in order to properly support dependent: nullify.
This commit is contained in:
parent
7dd27be1a2
commit
622485ae4b
|
@ -121,7 +121,9 @@ module ActiveRecord
|
|||
end
|
||||
|
||||
def nullify_owner_attributes(record)
|
||||
record[reflection.foreign_key] = nil
|
||||
Array(reflection.foreign_key).each do |foreign_key_column|
|
||||
record[foreign_key_column] = nil unless foreign_key_column.in?(Array(record.class.primary_key))
|
||||
end
|
||||
end
|
||||
|
||||
def transaction_if(value, &block)
|
||||
|
|
|
@ -145,6 +145,28 @@ class HasOneAssociationsTest < ActiveRecord::TestCase
|
|||
assert_not_predicate developer, :persisted?
|
||||
end
|
||||
|
||||
def test_nullification_on_cpk_association
|
||||
book = Cpk::Book.create!(author_id: 1, number: 2)
|
||||
other_book = Cpk::Book.create!(author_id: 3, number: 4)
|
||||
order = Cpk::OrderWithNullifiedBook.create!(book: book)
|
||||
|
||||
order.book = other_book
|
||||
|
||||
assert_nil book.order_id
|
||||
assert_nil book.shop_id
|
||||
end
|
||||
|
||||
def test_nullification_on_cpk_association_with_pk_column
|
||||
chapter = Cpk::Chapter.create!(author_id: 1, number: 2)
|
||||
other_chapter = Cpk::Chapter.create!(author_id: 1, number: 4)
|
||||
book = Cpk::NullifiedBook.create!(chapter: chapter, number: 1, author_id: 1)
|
||||
|
||||
book.chapter = other_chapter
|
||||
|
||||
assert_nil chapter.book_number
|
||||
assert_not_nil chapter.author_id
|
||||
end
|
||||
|
||||
def test_natural_assignment_to_nil_after_destroy
|
||||
firm = companies(:rails_core)
|
||||
old_account_id = firm.account.id
|
||||
|
|
|
@ -7,3 +7,4 @@ require_relative "cpk/review"
|
|||
require_relative "cpk/order_agreement"
|
||||
require_relative "cpk/order_tag"
|
||||
require_relative "cpk/tag"
|
||||
require_relative "cpk/chapter"
|
||||
|
|
|
@ -6,6 +6,8 @@ module Cpk
|
|||
|
||||
belongs_to :order, autosave: true, query_constraints: [:shop_id, :order_id]
|
||||
belongs_to :author, class_name: "Cpk::Author"
|
||||
|
||||
has_many :chapters, query_constraints: [:author_id, :book_number]
|
||||
end
|
||||
|
||||
class BestSeller < Book
|
||||
|
@ -14,4 +16,8 @@ module Cpk
|
|||
class BrokenBook < Book
|
||||
belongs_to :order
|
||||
end
|
||||
|
||||
class NullifiedBook < Book
|
||||
has_one :chapter, query_constraints: [:author_id, :book_number], dependent: :nullify
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Cpk
|
||||
class Chapter < ActiveRecord::Base
|
||||
self.table_name = :cpk_chapters
|
||||
# explicit definition is to allow schema definition to be simplified
|
||||
# to be shared between different databases
|
||||
self.primary_key = [:author_id, :number]
|
||||
|
||||
belongs_to :book, query_constraints: [:author_id, :book_number]
|
||||
end
|
||||
end
|
|
@ -20,4 +20,8 @@ module Cpk
|
|||
class OrderWithPrimaryKeyAssociatedBook < Order
|
||||
has_one :book, primary_key: :id, foreign_key: :order_id
|
||||
end
|
||||
|
||||
class OrderWithNullifiedBook < Order
|
||||
has_one :book, query_constraints: [:shop_id, :order_id], dependent: :nullify
|
||||
end
|
||||
end
|
||||
|
|
|
@ -249,6 +249,13 @@ ActiveRecord::Schema.define do
|
|||
t.integer :shop_id
|
||||
end
|
||||
|
||||
create_table :cpk_chapters, primary_key: [:author_id, :number], force: true do |t|
|
||||
t.integer :author_id
|
||||
t.integer :number
|
||||
t.integer :book_number
|
||||
t.string :title
|
||||
end
|
||||
|
||||
create_table :cpk_authors, force: true do |t|
|
||||
t.string :name
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue