Самостоятельное соединение Rails с ассоциацией has_many

Я пытаюсь написать приложение, подобное IMDB, на рельсах.

Я создал модель Movie. У каждого фильма есть много рекомендаций фильмов (которые также являются экземплярами фильма).

Я не знаю, как добавить ассоциацию «has_many», как написать файл миграции или как добавить рекомендуемые фильмы к каждому фильму.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
90
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

При создании миграции вам необходимо определить, какую ссылку на модель вы хотите назначить.

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

Другие вопросы по теме