0

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?

Aaron Cohen
  • 132
  • 8
  • Not much to go on. But, I'd say go with polymorphic. – jvillian Aug 22 '18 at 23:13
  • what kind of detail would help? I don't quite get what the polymorphic association would be if, say, I have 5+ different document types that all have many associated documents that can be any type. – Aaron Cohen Aug 22 '18 at 23:15
  • Is `Drawing` an example of `Document`? If so, what other kind of documents are there? Are the associations always 1:M? Or, are they ever M:M? – jvillian Aug 22 '18 at 23:18
  • Yes, sorry, Drawing is an example of a type of document. The other document types are `Rendering` `Sketch` and `ShopDrawing`. It's always many to many -- a given `Drawing` (or any other document type) has many associated documents, and thus could be associated the other way to many other documents. – Aaron Cohen Aug 22 '18 at 23:25
  • You might want to consider multiple table inheritance. You store the "common" columns in a single table and specifics in their own table. Or why not consider a schema-less document store like Mongoid which seems like a perfect fit. – max Aug 22 '18 at 23:28
  • I've never used a schema-less store, and since within each document type itself there's a consistent schema, and the rest of the app seems to be relational (users, projects, companies, sets of documents, etc) would I be losing out by using something like Mongoid? Is there a good resource for evaluating what use cases are best? – Aaron Cohen Aug 22 '18 at 23:36

1 Answers1

0

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).

jvillian
  • 19,953
  • 5
  • 31
  • 44