Question

How should I structure this Rails association?

Problem

So basically a user can create a dataset, and then create graphs off of it. I want the user to be able to create a project, and tag datasets or graphs with multiple projects. If a dataset is tagged with a project, it should not automatically tag all the graphs that belong to it (the dataset).

I'm a bit of a Rails association noob. Reading through the docs it sounds like I could do something like this.

  1. "dataset" has_many "graphs".
  2. "project" has_many "datasets" and "graphs".
  3. "dataset" has_many "projects".
  4. "graph" has_many "projects".

Solution: (is this correct?)

4 models: Dataset, Graph, Project, ProjectContent

For #1:

Dataset has_many Graphs
Graph belongs_to Dataset

For #2:

Project has_many datasets, through: :project_content
Project has_many graphs, through: :project_content

For #3:

Dataset has_many projects, through: project_content

For #4:

Graph has_many projects, through: project_content
Was it helpful?

Solution

This yells out "Polymorphic" to me, pretty much the default use case ;)

Tag Model:

belongs_to :taggable, :polymorphic => true
belongs_to :project

Project Model:

has_many :tags
has_many :datasets, :through => :tags, :source => :taggable, :source_type => 'Dataset'
has_many :graphs, :through => :tags, :source => :taggable, :source_type => 'Graph'

Graph Model:

belongs_to :dataset
has_many :tags, :dependent => :destroy
has_many :projects, :as => :taggable

Dataset Model:

has_many :graphs
has_many :tags, :dependent => :destroy
has_many :projects, :as => :taggable

If you do NOT want to go with a polymorphic model, your approach seems correct.

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