Question

I am going back and forth between three different ways to implement a has_many through relationship and I need some help deciding which is best.

At a basic level I have Contributor models which holds an individual's details, and I have a Project model to which the contributors can contribute. They can contribute in a number of different ways; a Contributor can be an editor, an author, a composer, a researcher etc. A Contributor can contribute in multiple ways to the same Project (for example they can be a composer and an editor), and they can contribute to multiple Projects.

So I've set up a join model called Contributorship. My question is what to do next. As far as I can see I have three options:

  1. Add a contribution_type attribute to Contributorship that holds the type of contribution (from a predefined enumeration). When I set up a relationship between Contributor and Project I set this the the appropriate value.

  2. Create multiple has_many through relationships on Project, one for each type of contribution. Each one still resolves to a Contributor, but uses a different foreign key on Contributorship.

  3. Ditch Contributorship and replace it with multiple join models - Editor, Author etc. which all resolve to Contributors.

Was it helpful?

Solution

I would go with the first option. Additionally I would define methods on project for easy access.

class Project < ActiveRecord::Base
  # ... relations defined
  Contributorship::TYPES.each do |c_type|
    define_method c_type do
      contributors.where( "contributorship.contribution_type" => c_type )
    end
  end
end

OTHER TIPS

Option 1 sounds clean and simple. It also allows you to fetch all the contributors regardless of type in one query. And you can always create finder methods on Project to fetch only editors or authors. It also allows to add contribution_types very easy.

Option 2 and 3 will work but are more rigid than the first option. They also require more tables and model classes to be created.

My advice: go for the simplest of solutions that will work now and wait until there are new requirements that require more complicated relations.

Are you afraid of ContributionType model?

Definitely first option but i would associate three models: Project, Contributor and ContributionType (new one, instead of enumeration) all through Contributorship model.

This gives you nearest representation of the reality and eventually gives generic freedom in any future moves (models complication, authorization and so on).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top