drewwyatt
drewwyatt

Reputation: 6027

Best way to structure has_many through with several models?

I am setting up a database of textbooks. A Book will look something like this:

Book

While a book would (obviously) only have one title or ISBN - I would like authors, subjects, universities, and professors to be a type of "tag". A book can be written by multiple authors, be used for multiple subjects in multiple classes taught by multiple professors. So I would like to setup a many-to-many relationship for each of those. e.g. an Author might look something like:

Author

It doesn't necessarily make sense to me for book to belong to author, or vise versa (though I could be wrong.) But I also don't know that creating a book_author_associations table, a book_jubjects_associations model, a book_classes_associations model, etc.

What is the best way to go about creating multiple many to manys like this?

Upvotes: 1

Views: 86

Answers (2)

David Aldridge
David Aldridge

Reputation: 52336

Having join tables is unavoidable in this situation.

You should go ahead and create separate tables for classes, subjects, authors, etc, because they have very different attributes. You should associate them with books through join tables that for the most part will have their own attributes.

For example, a contributor to a book could be an author, or they could be an editor, or a photographer, or a translator, or any number of other roles, and that role would be an attribute of the association between books and authors (better to call them contributors).

For more information on this sort of thing you might look at EDItEUR's Onix codelists for ideas about book metadata structure. http://www.editeur.org/14/Code-Lists/

Upvotes: 1

MrYoshiji
MrYoshiji

Reputation: 54882

No test, but should work in theory:

Book
  has_many :book_associations
  has_many :associations, through: :book_associations

BookAssociation
  belongs_to :book
  belongs_to :association, polymorphic: true
  validates :book_id, presence: true
  validates :association_id, presence: true
  validates :association_type, presence: true

Author
  has_many :book_associations, as: :association
  has_many :books, through: :book_associations

Subject
  has_many :book_associations, as: :association
  has_many :books, through: :book_associations

Upvotes: 3

Related Questions