Rails through-model 创建修改

Rails through-model modification on creation

我不确定这个问题最有用的标题是什么,但情况是这样的。我的应用程序中的模型可以通过直通模型 link 自身的其他示例:

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等等。标签应反映这一点,例如 "record A replaces Record B"、"record B is_replaced_by record A" 等。一种方法是像上面的例子那样使用两个标签,另一种方法是只使用 link "A replaces B" 并且在查看 B 时查找 links到它发现它被替换为 A.

我更喜欢后一种解决方案,但这提出了如何使其与控制器一起工作的问题。由于这是一个 API-only 应用程序,我可以通过发布以下参数来创建记录:

{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

但是,运气不好。大概 "record" 还不存在,这无济于事。我也想知道在保存后删除和 re-creating link,反转,但我需要 运行 一些复杂的验证,具体取决于记录的标签和内容,所以这个可能很棘手。

有人有什么建议吗?

最后,一个更简单的解决方案是从 Record 中删除 accepts_nested_attributes_for,然后让 front-end 应用程序对 record_associations_controller 进行单独的 post 以创建的关系。然后,两个记录都已经存在,并且可以按照用户喜欢的顺序提供它们的 ID。