How should I model different document types?

85 views Asked by At

I am building a Ruby On Rails API that helps manage construction documents -- there are a number of different types of documents that all have different fields, so I currently have a model for each.

However, I also would like the ability to refer to these documents in general, as each document can have an arbitrary number of associated documents, which can be of any document type. I'd like to be able to write something like

class Drawing < ApplicationRecord
  ...

  has_many :associated_documents

Where all I need is the name, id, and type of the associated documents (essentially so that one can easily navigate between related documents in the front-end)

Is this a use case for Single Table Inheritance? Is there a way to do this with Polymorphic Associations? Since the front-end use case is a list of links, should I just store the links?

1

There are 1 answers

0
jvillian On

Given that you have a M:M relationship where arbitrary Classes (Documents) can be associated, I would think you would look at a double-sided polymorphic association.

You might have an DocumentAssociation class, something like:

# == Schema Information
#
# Table name: document_associations
#
#  id                         :integer          not null, primary key
#  base_document_type         :string
#  base_document_id           :integer
#  associated_document_type   :string
#  associated_document_id     :integer
#  created_at                 :datetime         not null
#  updated_at                 :datetime         not null
#
class DocumentAssociation < ApplicationRecord
  belongs_to :base_document,        polymorphic: true
  belongs_to :associated_document,  polymorphic: true
end

And then something like:

class Drawing < ApplicationRecord
  has_many :base_document_associations, class_name: 'DocumentAssociation', as: :base_document
  has_many :associated_documents, through: :base_document_associations
end

That's probably directionally correct, but there is likely some fiddling you'll have to do. You'll also have to do some extra lifting if you want to be able to navigate in both directions (i.e., for a given Drawing you want all associations where the Drawing is both the base_document and the associated_document).