Rails多态关联+ fields_for

时间:2011-08-12 20:20:43

标签: ruby-on-rails forms polymorphism

我正试图围绕如何使用多态关联设置此架构:

“文档”有一个元数据对象,但这可以是“PDFMetaData”或“TXTMetaData”。

我担心的是:

要设置此关联,我可以执行此操作

class Document
  belongs_to :metadata, :polymorphic => true
end

class PDFMetaData
  has_one :document, :as => :metadata
end

class TXTMetaData
  has_one :document, :as => :metadata
end

这样可行,但对我来说感觉有点逆转:文档has_one元数据对象,而不是相反?

此外,在尝试为新文档创建嵌套表单时,我遇到了问题。我知道我可以使用fields_for,但我怎么知道它是什么类型的对象? (PDFMetaData或TXTMetaData)。我是否必须根据我的文档类型呈现单独的部分?

我害怕后者与我的第一个问题联系在一起,而且我正在做一些非常错误的事情。

由于

1 个答案:

答案 0 :(得分:0)

虽然我可以看到你对来自于belongs_to&的安排的混淆。在这种情况下,has_one的基本原理基于foreign_key在数据库模式中的位置。文档表包含将其与PdfMetaData对象相关联的foreign_key,因此没有理由相反地描述关系,因为没有办法建立has_many关系(如何在1中存储多个外键)数据库行?)

希望这有意义......但是在第二个问题上,解决方案取决于TXTMetaDataPDFMetaData类的有效属性列表。如果它们具有相同的属性(或者至少您希望在表单中提供的属性相同)那么你应该没问题

fields_for :metadata do |meta_fields|
  meta_fields.text_field :attr
  meta_fields.text_fields :attr2
end

等等

如果您想要公开不同的属性,那么我建议您检测元数据对象的类并采取相应的行动,例如

meta_obj = document.metadata
fields_for :metadata, meta_obj do |meta_fields|
  if meta_obj.is_a?(PDFMetaData)
    meta_fields.text_field :attr
    meta_fields.text_fiels :attr2
  elsif meta_obj.is_a?(TXTMetaData)
    meta_fields.text_field :other_attr
    meta_fields.text_fiels :other_attr2
  end
end