次のようなSTIセットアップがあります。
class Document < ActiveRecord::Base
attr_accessible :name, description
# Basic stuff omitted
end
class OriginalDocument < Document
has_many :linked_documents, foreign_key: :original_document_id, dependent: :destroy
end
class LinkedDocument < Document
belongs_to :original_document
# Delegation, because it has the same attributes, except the name
delegate :description, to: :original_document
end
ここで、 を複製して、独自の名前でLinkedDocument
として保存し、属性値を複製したままにします。OriginalDocument
ただし、どこかで複製が after_* コールバックで委任されたメソッドにアクセスしたいため、私のアプローチは失敗しています。
class LinkedDocument < Document
def unlink_from_parent
original = self.original_document
copy = self.becomes OriginalDocument
copy.original_document_id = nil
copy.description = original.description
copy.save
end
end
これはRuntimeError: LinkedDocument#description delegated to original_document.description, but original_document is nil
.
保存クエリには型が含まれているため、強制するために追加copy.type = 'OriginalDocument'
を行うことは機能しません。UPDATE documents SET [...] WHERE documents.type IN('OriginalDocument') [...]
. これは失敗します。トランザクションの時点で、オブジェクトのタイプはまだ であるからですLinkedDocument
。
オブジェクトをコピーして別のオブジェクトにするクリーンな方法は何でしょうか? コピーしたいすべての属性を 呼び出すことを考えupdate_column
ましたが、そのような洗練されていない方法で行う前に、ここで質問したいと思いました。type