开发者

Rails: How to handle model subclassing?

开发者 https://www.devze.com 2023-04-09 04:21 出处:网络
There are ten ways to do anything but what is the best practice approach to organizing the Document and Section models described below in Rails?

There are ten ways to do anything but what is the best practice approach to organizing the Document and Section models described below in Rails?

Documents can have n number of sections. Each Section can be a specialized type of section with its own attributes and associations differing from other sections. And each Document needs to track a section order state for all of the sections associated with it regardless of type.

I could create model classes for each Section type and associate them on Document as has_many SectionTypeA, has_many SectionTypeA and write a sorting mechanism to put together a sorted collection of all types for the given document.

I looked into Single Table Inheritance开发者_如何转开发. But the STI approach seems questionable when the specialized attributes are more complicated than a few string or integer fields. Sections will have attributes that map to database text columns and their own section has_many, has_one associations.

Here's a rough outline of the elements described:

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


This seems like it could be solved with a reverse polymorphic association like:

# 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


Take a look at polymorphic associations. Maybe you can create a 'sectionable' type for your different Section types and put those in one polymorphic association in Document.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号