Ecto (Phoenix) 中的外键数组
Array of foreign keys in Ecto (Phoenix)
我是网络开发的初学者,请原谅我的知识不足。
我有一个 Teacher
和一个 Student
Ecto 架构。它们应该按照以下规则通过另一个名为 Class
的模式链接:
每个class只有一个老师,并且有一组学生。
每个老师都可以成为许多 classes
的一部分
每个学生都可以成为许多 classes 的一部分。
这是我到目前为止构建的架构:
# Part of student.ex
schema "students" do
field :active, :boolean, default: false
field :birthday, :date
field :email, :string, unique: true
field :firstname, :string
field :lastname, :string
field :phone, :string, unique: true
belongs_to :classes, Class, foreign_key: :class_id
many_to_many :teachers, Users.Teacher, join_through: "classes"
timestamps()
end
# Part of teacher.ex
schema "teachers" do
field :active, :boolean, default: false
field :birthday, :date
field :email, :string, unique: true
field :firstname, :string
field :lastname, :string
field :phone, :string, unique: true
belongs_to :classes, Class, foreign_key: :class_id
many_to_many :students, Users.Student, join_through: "classes"
timestamps()
end
# Part of class.ex
schema "classes" do
field :end_date, :date
field :time, :time
field :level, :string
field :start_date, :date
field :title, :string
has_many :students, Users.Student
has_one :teacher, Users.Teacher
embeds_many :sessions, Session
timestamps()
end
这里看起来一切正常。但问题是,如何在迁移文件中指定 "an array of student ids" ?以下是迁移函数:
# Part of students migration file. It's the same for teachers.
def change do
create table(:students) do
add :firstname, :string, null: false, size: 32
add :lastname, :string, null: false, size: 32
add :phone, :string, null: false, size: 16
add :email, :string, size: 32
add :birthday, :date
add :active, :boolean, default: false, null: false
timestamps()
end
create(unique_index(:students, [:phone]))
end
这就是我现在真正陷入困境的地方:
def change do
create table(:classes) do
add :title, :string, null: false
add :level, :string
add :hours, :string, null: false
add :start_date, :date
add :end_date, :date
add :teacher_id, references(:teachers), primary_key: true
# HERE! How do I create a column for an array of student_id foreign keys?
timestamps()
end
create(index(:classes, [:teacher_id]))
end
提前致谢。
的文档中所述
You should use belongs_to
in the table that contains the foreign key. Imagine a company <-> employee
relationship. If the employee
contains the company_id
in the underlying database table, we say the employee
belongs to company
.
In fact, when you invoke this macro, a field with the name of foreign key is automatically defined in the schema for you.
相反,Ecto.Schema.has_one/3
nor Ecto.Schema.has_many/3
均不暗示相应字段的存在。一切都由 link.
的另一端完成
也就是说,
students
架构应该有 class_id
字段(已经存在)
classes
可能应该有 teacher_id
(假设老师可能有几个 class。)要做到这一点,请将 teachers
改为 has_many :classes
belongs_to :class
和 将 classes
更改为 belongs_to :teacher
而不是 has_one :teacher
.
是否希望学生属于多个 classes,架构不正确。在 students
的每个记录中存在 class_id
外键意味着每个学生都与这个特定的 class 相关联。你应该删除
belongs_to :classes, Class, foreign_key: :class_id
来自 students
,因为它首先将一个学生粘在一个 class 上。然后你必须引入 classes_to_students
join schema,如这里所述 Ecto.Schema.many_to_many/3
.
我是网络开发的初学者,请原谅我的知识不足。
我有一个 Teacher
和一个 Student
Ecto 架构。它们应该按照以下规则通过另一个名为 Class
的模式链接:
每个class只有一个老师,并且有一组学生。
每个老师都可以成为许多 classes
的一部分
每个学生都可以成为许多 classes 的一部分。
这是我到目前为止构建的架构:
# Part of student.ex
schema "students" do
field :active, :boolean, default: false
field :birthday, :date
field :email, :string, unique: true
field :firstname, :string
field :lastname, :string
field :phone, :string, unique: true
belongs_to :classes, Class, foreign_key: :class_id
many_to_many :teachers, Users.Teacher, join_through: "classes"
timestamps()
end
# Part of teacher.ex
schema "teachers" do
field :active, :boolean, default: false
field :birthday, :date
field :email, :string, unique: true
field :firstname, :string
field :lastname, :string
field :phone, :string, unique: true
belongs_to :classes, Class, foreign_key: :class_id
many_to_many :students, Users.Student, join_through: "classes"
timestamps()
end
# Part of class.ex
schema "classes" do
field :end_date, :date
field :time, :time
field :level, :string
field :start_date, :date
field :title, :string
has_many :students, Users.Student
has_one :teacher, Users.Teacher
embeds_many :sessions, Session
timestamps()
end
这里看起来一切正常。但问题是,如何在迁移文件中指定 "an array of student ids" ?以下是迁移函数:
# Part of students migration file. It's the same for teachers.
def change do
create table(:students) do
add :firstname, :string, null: false, size: 32
add :lastname, :string, null: false, size: 32
add :phone, :string, null: false, size: 16
add :email, :string, size: 32
add :birthday, :date
add :active, :boolean, default: false, null: false
timestamps()
end
create(unique_index(:students, [:phone]))
end
这就是我现在真正陷入困境的地方:
def change do
create table(:classes) do
add :title, :string, null: false
add :level, :string
add :hours, :string, null: false
add :start_date, :date
add :end_date, :date
add :teacher_id, references(:teachers), primary_key: true
# HERE! How do I create a column for an array of student_id foreign keys?
timestamps()
end
create(index(:classes, [:teacher_id]))
end
提前致谢。
You should use
belongs_to
in the table that contains the foreign key. Imagine acompany <-> employee
relationship. If theemployee
contains thecompany_id
in the underlying database table, we say theemployee
belongs tocompany
. In fact, when you invoke this macro, a field with the name of foreign key is automatically defined in the schema for you.
相反,Ecto.Schema.has_one/3
nor Ecto.Schema.has_many/3
均不暗示相应字段的存在。一切都由 link.
也就是说,
students
架构应该有class_id
字段(已经存在)classes
可能应该有teacher_id
(假设老师可能有几个 class。)要做到这一点,请将teachers
改为has_many :classes
belongs_to :class
和 将classes
更改为belongs_to :teacher
而不是has_one :teacher
.
是否希望学生属于多个 classes,架构不正确。在 students
的每个记录中存在 class_id
外键意味着每个学生都与这个特定的 class 相关联。你应该删除
belongs_to :classes, Class, foreign_key: :class_id
来自 students
,因为它首先将一个学生粘在一个 class 上。然后你必须引入 classes_to_students
join schema,如这里所述 Ecto.Schema.many_to_many/3
.