Я пытаюсь написать приложение, подобное IMDB, на рельсах.
Я создал модель Movie. У каждого фильма есть много рекомендаций фильмов (которые также являются экземплярами фильма).
Я не знаю, как добавить ассоциацию «has_many», как написать файл миграции или как добавить рекомендуемые фильмы к каждому фильму.
При создании миграции вам необходимо определить, какую ссылку на модель вы хотите назначить.
create_table :student do |t|
t.references :class, foreign_key: true
end
Здесь я говорю своей таблице классов хранить первичный ключ ученика в качестве внешнего ключа, после миграции в классе появится столбец с именем student_id, в котором хранится pk таблицы ученика. Затем я определю ассоциацию в файле модели класса.
class student < ApplicationRecord
belongs_to :class
end
Это поможет мне в запросе, чтобы я мог написать
student= Student.find 'student_id'
class = student.class
Это вернет класс этого ученика. Для has_many процедура такая же, но она вернет вам массив
У вас отношение «многие ко многим», а это значит, что нам нужна таблица соединений Recommendation
.
Создайте модель и файлы миграции с помощью генератора:
bin/rails generate model Movie
bin/rails generate model Recommendation
Затем обновите миграции:
# 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
Запустите миграции:
bin/rails db:migrate
Модели установки:
# 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
Протестируйте в консоли 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>]
или вот так:
>> 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