stevenpslade
stevenpslade

Reputation: 360

How should these Rails Models be associated?

I have over thought this to the point that I'm only getting confused now.

I have a Rails app with the following as models: User, Site, Tutorial, TutorialStep.

A user can create many tutorials and each tutorial has a site it lives on, and each tutorial has many tutorial steps.

The model I'm having the issue with is Site.

A user has many tutorials and has many tutorials steps through tutorial. A tutorial belongs to a user and has many tutorial steps and lastly a tutorial step belongs to a tutorial.

Now should a site belong to a user and a tutorial, or just a tutorial?

Upvotes: 1

Views: 59

Answers (4)

Vishal Taj PM
Vishal Taj PM

Reputation: 1359

As far as i understand from your question you can use has_one relation.

has_one : Specifies a one-to-one association with another class

you can create a has_one relation with site and tutorial

app/models/user.rb

has_many :tutorials,->{ includes :site}
has_many :tutorial_steps, through: :tutorials

includes is eager loading technique which lets you to fetch site along with the tutorial relation

app/models/tutorial.rb

belongs_to :site
belongs_to :user
has_many :tutorial_steps

app/models/site.rb

  has_one :tutorial

app/models/tutorial_step.rb

belongs_to :tutorial

Upvotes: 0

John Hayes-Reed
John Hayes-Reed

Reputation: 1428

I would structure the relations as follows:

class User < ApplicationRecord
  has_many :tutorials
  has_many :sites, through: :tutorials
  ...
end

class Site < ApplicationRecord
  has_many :tutorials
  has_many :users, through: :tutorials
  ...
end

class Tutorial < ApplicationRecord
  has_many :tutorial_steps
  belongs_to :user
  belongs_to :site
  ...
end

class TutorialStep < ApplicationRecord
  belongs_to :tutorial
  ...
end

Making a Site belong to a User Binds that site to a single user only, which then means that multiple users cannot place tutorials on the same site, you would have to make duplicate entries of the same site to be able to achieve this, which in my opinion is not very good model design, because if in real life multiple users have different tutorials on the same site, you want to be able to reflect that same behaviour in your models and data. Therefore if you want to be able to reference sites from a User, and reference users from a Site, I would recommend using a has many through relation on the table that links them, ie the tutorial table, like I have show above.

Upvotes: 1

Rajdeep Singh
Rajdeep Singh

Reputation: 17834

It should look like this,

user.rb

has_many :tutorials
has_many :tutorial_steps, through: :tutorials

site.rb

has_many :tutorials

tutorial.rb

has_many :tutorial_steps
belongs_to :user
belongs_to :site

tutorial_step.rb

belongs_to :tutorial
has_one :user, through: :tutorial
has_one :site, through: :tutorial

Hope that helps!

Upvotes: 0

SoWhat
SoWhat

Reputation: 5622

User

has_many :tutorials

Site

has_many :tutorials

Tutorial

has_many :tutorial_steps
belongs_to :user
belongs_to :site

Tutorial would need site id and user id to correctly map association to user and site

Tutorial Table (... user_id,site_id)

Upvotes: 0

Related Questions