Rails: как работать с подклассами моделей? - PullRequest
0 голосов
/ 29 сентября 2011

Существует десять способов сделать что-нибудь, но каков наилучший практический подход к организации моделей Document и Section, описанных ниже в Rails?

Документы могут иметь n разделов. Каждый Section может быть специализированным типом раздела с его собственными атрибутами и ассоциациями, отличающимися от других разделов. И каждый Document должен отслеживать состояние порядка разделов для всех связанных с ним разделов независимо от их типа.

Я мог бы создать классы моделей для каждого типа Section и связать их с Document как has_many SectionTypeA, has_many SectionTypeA и написать механизм сортировки, чтобы собрать отсортированную коллекцию всех типов для данного документа.

Я посмотрел на наследование одной таблицы. Но подход STI кажется сомнительным, когда специализированные атрибуты являются более сложными, чем несколько строковых или целочисленных полей. Разделы будут иметь атрибуты, которые сопоставляются с текстовыми столбцами базы данных, и их собственный раздел имеет ассоциации has_many, has_one.

Вот примерный план описанных элементов:

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 ]

2 голосов
/ 03 октября 2011

Кажется, что это можно решить с помощью обратной полиморфной ассоциации, такой как:

# 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
0 голосов
/ 29 сентября 2011

Взгляните на полиморфные ассоциации .Может быть, вы можете создать «секционируемый» тип для ваших различных типов Section и поместить их в одну полиморфную ассоциацию в Document.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...