ruby-on-railshas-and-belongs-to-many

Creating a habtm relationship


I'm creating a movie watchlist app in rails/angular. For this I have a table with users and a table with movies.

At the moment I create a unique record for each movie added, this results in several copies of existing records but all with different user id's. So I'm looking into the has_and_belongs_to_many relationship in rails. But I'm having some trouble using it in my app.

As I see it a user can have multiple movies, and a movie can have multiple users. So I've added this to the models,

movie.rb

has_and_belongs_to_many :users

user.rb

has_and_belongs_to_many :movies

I've also created a migration,

class AddMoviesUsersJoinTable < ActiveRecord::Migration
  def self.up
    create_table :movies_users, :id => false do |t|
      t.integer :movie_id
      t.integer :user_id
    end
  end

  def self.down
    drop_table :movies_users
  end
end

But I'm unsure on how this is all connected. With the migration I've added a join table with 2 colums. Movie_id and user_id. Does the movie_id value in the movie_users table correspond to the movie_id in the movie table? Same goes for the user_id, does that correspond to the user_id in the user table?

Also, how do I connect the two id's together. Do I have to add "something" to the movies_users join table when I create a new movie?

This is my current movies_controller.rb

def create
  respond_with Movie.create(movie_params.merge(user_id: current_user.id))
end

private
def movie_params
  params.require(:movie).permit(:title, :image, :release_date, :movie_id)
end

//EDIT//

I've added the has_many_belongs_to relations to my movie and user model and I created a join table called movies_users with 2 colums user_id and movie_id.

I've created 2 accounts on my page and added the movie Creed with them. This is the result in my rails console Movie.all

#<Movie id: 1, title: "Creed", user_id: 1, movie_id: "312221">, 
#<Movie id: 2, title: "Creed", user_id: 2, movie_id: "312221">

As you can see it still creates 2 different movies although they have the same values, except the user_id. So it looks like there's no checking to see if an value (the movie_id) already exists. I thought this was a part of the habtm relation.


Solution

  • Rather than habtm i would use has_many :through

    class User
      has_many :movies_users
      has_many :movies, :through => :movies_users
    
    class Movie
      has_many :movies_users
      has_many :users, :through => :movies_users  
    
    class MoviesUser
      belongs_to :movie
      belongs_to :user
    

    Now you will have a single movie record per movie and create a movie_user record when a user watches a movie. You can do this RESTfully with a MoviesUsersController, which you call the create action, passing through params = {:movies_user => {:user_id => 123, :movie_id => 456}}