我不确定该问题最有用的标题是什么,但这是场景。我的应用程序中的模型可以通过直通模型链接到自身的其他示例:
class Record < ApplicationRecord
has_many :record_associations
has_many :linked_records, through: :record_associations
has_many :references, foreign_key: :linked_record_id, class_name: 'RecordAssociation'
has_many :linking_records, through: :references, source: :record
accepts_nested_attributes_for :record_associations, allow_destroy: true
end
class RecordAssociation < ApplicationRecord
belongs_to :record
belongs_to :linked_record, :class_name => 'Record'
belongs_to :label
end
class Label < ApplicationRecord
has_many :record_associations
end
因此,此模型是有方向性的,每个记录具有许多linked_records,linking_records等。标签应反映这一点,例如“记录A替换记录B”,“记录B is_replaced_by记录A”等等。一种方法是像上面的示例中那样具有两个标签,另一种方法是仅具有一个链接“ A替换B”,并且在查看B时查找指向它的链接以发现被替换为答:
我更希望使用后一种解决方案,但这提出了如何使其与控制器一起工作的问题。由于这是仅API的应用程序,因此我可以通过发布以下参数来创建记录:
{record: {
name: 'example',
record_association_attributes: {
linked_record_id: 1,
label_id: 2
}
}}.to_json
但是,如果标签指定记录和linked_record应该相反,那么我如何创建它呢?我想到要在record_association(例如_reverse)上传递一个附加的虚拟属性,如果指定了该属性,它将在RecordAssociation中执行以下操作:
before_validation :swap_links
def swap_links
if _reverse == 1
record, linked_record = linked_record, record
end
end
但是,没有运气。大概“记录”还不存在,这无济于事。我还想知道如何在保存后删除并重新创建反向链接,但是我需要根据标签和记录的内容运行一些复杂的验证,因此这可能很棘手。
有人有什么建议吗?
答案 0 :(得分:0)
最后,一个更简单的解决方案是从Record中删除accepts_nested_attributes_for,并让前端应用程序在record_associations_controller上单独发布以创建关系。然后,两个记录都已经存在,并且可以按照用户希望的顺序提供其ID。