class Appointment < ApplicationRecord
belongs_to :teacher
belongs_to :student
end
class Teacher < User
has_many :appointments
end
class Student < User
has_many :appointments
end
class User < ApplicationRecord
has_secure_password
validates :username, presence: true
validates :username, uniqueness: true
validates :username, length: { minimum: 4 }
validates :email, presence: true
validates :email, uniqueness: true
end
Схема:
ActiveRecord::Schema[7.0].define(version: 2024_06_06_180259) do
create_table "appointments", force: :cascade do |t|
t.datetime "start_datetime"
t.integer "teacher_id", null: false
t.integer "student_id", null: false
t.string "notes"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "status"
t.index ["teacher_id"], name: "index_appointments_on_teacher_id"
t.index ["student_id"], name: "index_appointments_on_student_id"
end
create_table "teachers", force: :cascade do |t|
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "students", force: :cascade do |t|
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "users", force: :cascade do |t|
t.string "email"
t.string "username"
t.string "password_digest"
t.string "first_name"
t.string "last_name"
t.string "type"
t.string "phone_number"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_foreign_key "appointments", "teachers"
add_foreign_key "appointments", "students"
end
Раньше у меня были проблемы с использованием STI для представления учителей и учеников в одной таблице базы данных пользователей. Но теперь я сделал отдельные таблицы для учителей и учеников. Тем не менее, я получаю сообщение об ошибке ограничения внешнего ключа. Я не уверен, что я делаю здесь неправильно. Похоже, я правильно сделал ассоциации. Может ли кто-нибудь провести меня сюда?
belongs_to :coach -> belongs_to :teacher@Alex Это функция Rails или подклассы обычно живут в той же базе данных, что и их родительский класс?
когда вы наследуете от другой модели, срабатывает все поведение STI, и подклассы используют таблицу своих родителей. api.rubyonrails.org/classes/ActiveRecord/ModelSchema/…





Вы можете разделить учителей и учеников на отдельные модели с помощью одной и той же подложки users таблицы. Это распространенная закономерность. Хотя я бы сделал это только в том случае, если между учителями и учениками существует логическая разница (в вашем примере она пока не продемонстрирована).
Если вы сделаете это, вам НЕ нужно будет создавать ни таблицу teachers, ни таблицу students в вашей базе данных. Будет лучше, если вы этого не сделаете.
Rails предполагает, когда вы используете belongs_to, что идентификатором является имя таблицы, но вы можете переопределить это.
class Appointment < ApplicationRecord
belongs_to :teacher, class_name: "User"
belongs_to :student, class_name: "User"
end
Вышеупомянутое скажет Rails искать teacher_id и student_id в столбце users.id и должно решить вашу проблему с ограничением внешнего ключа.
К сожалению, это не работает, я получаю следующее: SQLite3::SQLException: no such table: main.students (ActiveRecord::StatementInvalid)
Было бы полезно, если бы вы добавили код, генерирующий эту ошибку.
Это по-прежнему исходный код, приведенный выше, с вашими изменениями, в частности добавлением class_name: "User". По какой-то причине здесь это не сработало, но добавление эквивалента в файл миграции при создании таблицы встреч и повторном выполнении миграции сработало. Я не уверен, почему ваше предложение не имело такого же эффекта.
Я думаю, что это могла быть проблема с SQLite, но сначала мне нужно подтвердить это в MySQL/Postgres. На данный момент исправлением был повторный запуск миграции для создания таблицы appointments с использованием приведенного ниже кода миграции, который смог успешно создать связь между встречами, учениками и преподавателями. Важным изменением является добавление ссылок foreign_key: { to_table: :users } для формальной связи с таблицей users. До этого момента никакие другие предложения не работали, но это устранило проблему. Я обновлю, когда у меня будет время проверить MySQL.
class CreateAppointments < ActiveRecord::Migration[7.0]
def change
create_table :appointments do |t|
t.datetime :start_datetime
t.references :teacher, null: false, foreign_key: { to_table: :users }
t.references :student, null: true, foreign_key: { to_table: :users }
t.string :status
t.timestamps
end
end
end
ты говоришь
Coaches, я вижуTeachers. вы все еще используете STI, наследуя отUser.