Question

I am building a website where users can create programming ideas for programming-courses school projects. They can view all ideas, and enroll (subscribe) into an idea that another user has created. The enroll button will be on the show page of a idea from a user

I have tried to create a relationshipsmodel that acts like a join table, but it didn't work out. Then my teacher told me i could create the has_many through association without creating a dedicated relationships table to connect the user and idea model though the enrollment.

I'm kind of new to rails and just finished the Rails tutorial by Michael Heartl.

This is my code:

class User < ActiveRecord::Base
  has_many :ideas
  has_many :enrolled_ideas, through: :enrollments, dependent: :destroy, class_name: "Idea"

class Idea < ActiveRecord::Base
    belongs_to :user

WebappProject::Application.routes.draw do
  resources :users 
  resources :sessions,   only: [:new, :create, :destroy]
  resources :ideas do
    member do
      get :enrolled
    end
  end

The ideas are on the home page (static_pages controller), which a user can click on. He then gets send to the show page of and idea (ideas_controller) via the show action. On this page (specific idea from a user) i want an "Enroll" button. So if a user clicks on it, the owner of the idea, can list on his user show page, all enrolled users.

Was it helpful?

Solution

There are 2 ways of doing Has And Belongs To Many (HABTM) tables in Rails, both use an intermediate table. What your teacher probably meant is that there is a way to do the HABTM relationship without adding a 3rd model. That way you can have:

class User < ActiveRecord::Base
  has_and_belongs_to_many :ideas
end

class Idea < ActiveRecord::Base
  has_and_belongs_to_many :users
end

This way you could run

User.first.ideas #to get all the ideas a user created or is subcribed to
Idea.first.users #to get all the users subscribed to an idea
Idea.first.users << User.first # to subscribe the first user to the first idea

But you still have to create a migration for the intermediate table following Rail's convetions which in this case would be:

class CreateUsersIdeas < ActiveRecord::Migration
  def change
    create_table :users_ideas do |t|
      t.belongs_to :user
      t.belongs_to :idea
    end
  end
end

you can read more about this relationship type at http://guides.rubyonrails.org/association_basics.html (2.6 The has_and_belongs_to_many Association)

The second way is more flexible since it lets you add fields in the relationship table does need an intermediate model like so:

class User < ActiveRecord::Base
  has_many :subscriptions
  has_many :ideas, through: :subscriptions
end

class Subscriptions < ActiveRecord::Base
  belongs_to :user
  belongs_to :idea
end

class Idea < ActiveRecord::Base
  has_many :subscriptions
  has_many :users, through: :subscriptions
end

Like in the first pattern you still have to create an intermediate table, this time it should be called subscriptions and reference both user and idea. Again you can read more on this on the same page just look for 2.4 The has_many :through Association.

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