I am trying to write an app like IMDB in rails.
I have created the Movie model. Every movie has many movie recommendations (which are also instances of Movie).
I don't know how to add the "has_many" association, how to write the migration file or how to add recommended movies to each movie.
CodePudding user response:
You have a many-to-many relationship, which means we need a join table Recommendation
.
Create model and migration files with a generator:
bin/rails generate model Movie
bin/rails generate model Recommendation
Then update migrations:
# db/migrate/20221023063944_create_movies.rb
class CreateMovies < ActiveRecord::Migration[7.0]
def change
create_table :movies do |t|
# TODO: add fields
end
end
end
# db/migrate/20221023064241_create_recommendations.rb
class CreateRecommendations < ActiveRecord::Migration[7.0]
def change
create_table :recommendations do |t|
t.references :movie, null: false, foreign_key: true
t.references :recommended_movie, null: false, foreign_key: { to_table: :movies }
end
end
end
Run migrations:
bin/rails db:migrate
Setup models:
# app/models/movie.rb
class Movie < ApplicationRecord
# NOTE: this is the relationship for join table
has_many :recommendations, dependent: :destroy
# NOTE: get movies from join table
has_many :recommended_movies, through: :recommendations
# this ^ is the name of the relationship in `Recommendation` we want
end
# app/models/recommendation.rb
class Recommendation < ApplicationRecord
belongs_to :movie
# NOTE: our foreign key is `recommended_movie_id` which rails infers
# from `:recommended_movie`, but we have to specify the class:
belongs_to :recommended_movie, class_name: "Movie"
end
Test it in the console bin/rails console
:
>> 3.times { Movie.create }
>> Movie.first.recommended_movies << [Movie.second, Movie.third]
>> Movie.first.recommended_movies
=> [#<Movie:0x00007f15802ec4c0 id: 2>, #<Movie:0x00007f15802ec3d0 id: 3>]
or like this:
>> Movie.second.recommendations << Recommendation.new(recommended_movie: Movie.first)
>> Movie.second.recommended_movies
=> [#<Movie:0x00007f158215ef20 id: 1>]
https://guides.rubyonrails.org/association_basics.html#the-has-many-through-association
https://guides.rubyonrails.org/association_basics.html#self-joins
CodePudding user response:
When creating a migration you need to define which model refrence you want to assign
create_table :student do |t|
t.references :class, foreign_key: true
end
here i am telling my class table to store primary key of student as foreign key after migration there will be a column in class named student_id which stores pk of student table. Then i will define association in class model file
class student < ApplicationRecord
belongs_to :class
end
This will help me in query so i can write
student= Student.find 'student_id'
class = student.class
This will return the class of that student. For has_many the procedure is same but it will return you the array