Rails:如何处理模型子类化?

时间:2011-09-29 19:47:32

标签: ruby-on-rails ruby-on-rails-3 activerecord ruby-on-rails-3.1

有十种方法可以做任何事情,但在Rails中组织下面描述的DocumentSection模型的最佳做法是什么?

文档可以包含n个部分。每个Section都可以是一种特殊类型的部分,其自身的属性和关联与其他部分不同。并且每个Document都需要跟踪与其关联的所有部分的部分顺序状态,而不管其类型。

我可以为每个Section类型创建模型类,并将它们与Document关联为has_many SectionTypeA,has_many SectionTypeA并编写排序机制以将已排序的集合放在一起给定文件的所有类型。

我研究了单表继承。但是当特殊属性比几个字符串或整数字段更复杂时,STI方法似乎有问题。节将具有映射到数据库文本列的属性以及它们自己的部分has_many,has_one association。

以下是所描述元素的大致轮廓:

Document
  Sections
  -Section Type A
    Title, freeform text
  -Section Type B
    Title, collection of urls
  -Section Type C
    Title, collection of images with title and collection of image comments

2 个答案:

答案 0 :(得分:2)

这似乎可以通过反向多态关联来解决,如:

# Models
class Document < ActiveRecord::Base
  has_many  :document_sections
  has_many  :freeform_sections, 
            :through => :document_sections, 
            :source => :section, 
            :source_type => 'FreeformSection'

  def add_section(section)
    self.freeform_sections << section if section.is_a? FreeformSection
  end
end

class DocumentSection < ActiveRecord::Base
  belongs_to :document
  belongs_to :section, :polymorphic => true
end

class FreeformSection < ActiveRecord::Base
  has_one :document_section, :as => :section
  has_one :document, :through => :document_section
end

# Migrations
class CreateDocuments < ActiveRecord::Migration
  def change
    create_table :documents do |t|
      t.string :name

      t.timestamps
    end
  end
end

class CreateDocumentSections < ActiveRecord::Migration
  def change
    create_table :document_sections do |t|
      t.integer :section_id
      t.string :section_type
      t.references :document

      t.timestamps
    end
  end
end

class CreateFreeformSections < ActiveRecord::Migration
  def change
    create_table :freeform_sections do |t|
      t.references :section

      t.timestamps
    end
  end
end

# Usage
document = Document.create :name => 'My Doc'
document.freeform_sections << FreeformSection.new
document.add_section FreeformSection.new
document.document_sections
document.freeform_sections

答案 1 :(得分:0)

看看polymorphic associations。也许您可以为不同的Section类型创建“可分段”类型,并将它们放在Document中的一个多态关联中。