Использование таблиц объединения в рубине на рельсах
Допустим, у меня две базы данных: одна для студентов и одна для классов. Я хотел бы иметь возможность добавлять классы к конкретному ученику, а также добавлять учеников в определенный класс. Я предполагаю, что мне нужно использовать таблицу соединений здесь, но я немного потерял, как их использовать. В конечном итоге мне хотелось бы сделать что-то вроде:
@class.students.find(@student_id)
и это скажет мне, есть ли учащийся в классе или нет. Я знаю, что отношения между классами и учениками - "has_many" и наоборот. Выполняет ли это "t.references: students" в файлах переноса? Я попытался добавить эту строку в свой файл миграции, а затем попытался найти что-то с помощью вышеприведенного утверждения, и это дало мне ошибку. Я новичок в RoR, поэтому я даже не уверен, что лучший способ добиться этого. Любая помощь приветствуется!
Ответы
Ответ 1
Да, это отношения "многие ко многим" (у класса много учеников, у ученика много классов). Для этого вы будете использовать отношение has_many :through
. Взгляните на документы для ActiveRecord::Associations
(Ctrl-F для "Association Join Models" ).
В процессе миграции t.references :students
заключается в том, как вы указываете отношение belongs_to
, поскольку оно просто добавляет столбец student_id
(который может содержать только один идентификатор, т.е. один ученик). Однако модель объединения будет иметь два столбца: student_id
и class_id
. (Кстати, вызов модели "Класс" в Ruby требует неприятностей. Могу ли я предложить "курс"?)
Ответ 2
Все верно, что сказал @Jordan, вот конкретные шаги, которые нужно предпринять:
- Создать migration:
rails g model CourseStudent
создает модель соединения для отношения n: m и перехода к соответствующей таблице.
-
Отредактируйте файл миграции CreateCourseStudent
, чтобы он содержал следующее:
class CreateCourseStudent < ActiveRecord::Migration
def change
create_table :course_students do |t|
# Your code comes here
t.integer :student_id
t.integer :course_id
# Here comes the generated code
t.timestamps
end
end
end
-
Запустите миграцию: rake db:migrate
. В результате таблица соединений теперь должна существовать в вашей базе данных.
-
Добавьте к моделям следующий код
class Course < ActiveRecord::Base
has_many :course_students
has_many :students, :through => :course_students
end
class Student < ActiveRecord::Base
has_many :course_students
has_many :courses, :through => :course_students
end
class CourseStudent < ActiveRecord::Base
belongs_to :student
belongs_to :course
end
Теперь вы можете использовать методы, сгенерированные методами belongs_to
и has_many
:
-
@course.students
-
@student.courses
Попробуйте найти все соответствующие факты и фрагменты в Rails Guides, там вы должны найти всю необходимую информацию для отслеживания. Удачи!
Ответ 3
Это старый вопрос, но на всякий случай кто-то спотыкается об этом, как и я, теперь вы можете иметь отношения has_and_belongs_to_many
. Итак, вы создали бы таблицу соединений:
create_join_table :students, :courses do |t|
t.integer :student_id
t.integer :course_id
end
И затем в моделях вы сказали бы, что студент has_and_belongs_to_many :courses
И курс has_and_belongs_to_many :students
. Нет необходимости создавать третий класс под названием CourseStudent. Эта ссылка содержит всю эту информацию