多对多关系与 2 FK 引用相同的 PK Laravel 8
Many to Many Relationship with 2 FK referencing from same PK Laravel 8
你好,我正在做一个 Laravel 项目,我必须分配一个 Mentorship «Mentoria»,一个 Mentor «Mentor» 和一个学生 «Mentorando»。学生和导师的数据来自用户 table(我使用 Spatie 为他们分配了角色),另一个 table 称为 «Mentoria» 因为存在多对多关系 i创建了名为 «utilizador_mentoria» 的枢轴 table 并具有 ID_Mentor、ID_Mentorando(两者都是来自用户 table 的 FK)和 ID_mentoria(来自 Mentoria table)。我将这两个模型定义为:
用户模型:
protected $casts = [
'email_verified_at' => 'datetime',
];
public function interesses(){
return $this->belongsToMany(AreaInteresse::class, 'utilizador_interesse', 'id_utilizador', 'id_interesse');
}
public function mentorias(){
return $this->belongsToMany(Mentoria::class, 'utilizador_mentoria', 'id_mentoria', 'id_mentorando', 'id_mentor');
}
ps: 我对其他型号有兴趣,工作正常。我的问题是 «mentorias»
Mentoria 模型:
public function users(){
return $this->belongsToMany(User::class, 'utilizador_mentoria','id_mentor','id_mentorando','id_mentoria');
}
有了这个,我试图从所有 Mentorias 获取数据,以及分配给那个 Mentoria 的 Mentor 的数据,但是当我在控制器上执行此代码时,数据来自用户看起来是空的,尽管我的数据库中充满了数据。试了echo测试,只显示Mentoria的数据,应该出现分配给那个MEntoria的Mentor的数据,是空的
来自控制器的代码:
public function mentorias(){
$mentorias = Mentoria::with('users')->get();
echo $mentorias;
return view('admin/mentorias/admin_mentorias', ['mentorias' => $mentorias]);
}
回显的输出
[{"id":2,"titulo":"teste","titulo_en":"test","descricao":"fe","descricao_en":"ewfwe","created_at":"2021-12-28T01:32:10.000000Z","updated_at":"2021-12-28T01:32:10.000000Z","users":[]}]
因为正如我已经说过的,我已经使用了 2 table 的多对多关系数据,但是每个 PK 只有 1 个 FK,而且它工作正常,我不知道为什么不是这样工作的。我已经检查过类似的问题,但是没有运气
编辑:
出于测试目的,我删除了从同一 PK 引用的两个 FK 之一的列,并且我设法工作,但是对于这个附加的 FK,我无法使其工作。我认为问题出在模型中的关系上,但我不知道如何让它工作
我重新排列了模型中的函数,就像现在一样
用户模型:
public function mentorias(){
return $this->belongsToMany(Mentoria::class, 'utilizador_mentoria', 'id_mentor', 'id_mentorando', 'id_mentoria');
}
Mentoria 模型:
public function users(){
return $this->belongsToMany(User::class, 'utilizador_mentoria','id_mentoria','id_mentorando','id_mentor');
我也试过从 main () 中取出 example «id_entorando» 并用 «withPivot» 方法把它放在后面,但还是不行
我不知道我是否正确理解了这个问题,但你的关系不是单一的“多对多”,而是两个“一对多”。最后,我将说明为什么将它们视为两个分离的关系很方便。
首先:如果一个用户可以有多个导师,但一个导师只能有一个导师(我想这是正在发生的事情),那么你应该使用“hasMany/belongsTo”对:
用户模型:
public function mentorias(){
return $this->hasMany(Mentoria::class);
}
Mentoria 模型:
public function user(){
return $this->belongsTo(User::class);
}
其次:完成与导师和学生之间的其他关系的场景:
用户模型:
public function mentorias(){
return $this->hasMany(Mentoria::class);
}
public function mentoria(){
return $this->belongsTo(Mentoria::class);
}
Mentoria 模型:
public function user(){
return $this->belongsTo(User::class);
}
public function mentorandos(){
return $this->hasMany(User::class);
}
mentorias
table 中应该有一个 user_id
列代表导师所属的老师:
Schema::table('mentorias', function (Blueprint $table) {
$table->unsignedInteger('user_id')->nullable();
});
而且 users
table 中还应该有一个 mentor_id
列,代表学生所属的导师:
Schema::table('users', function (Blueprint $table) {
$table->unsignedInteger('mentoria_id')->nullable();
});
第三:用户模型的这种双重表示可能会导致混淆,因为两个不同的对象(教师和学生)正在使用相同的模型但并不意味着同时具有两种关系:不应该指导教师学生不应该领导指导。
为了更好地管理教师和学生并防止混淆,您可以创建额外的模型来继承用户模型并为它们定义关系(而不是用户模型),这样您就可以限制字段和关系对于他们中的每一个。
用户模型:
// No relationships
教师模型:
// Extending from User allows you to have all the User Model functionality
class Teacher extends User
{
public function mentorias(){
return $this->hasMany(Mentoria::class)->with('students');
}
}
学生模型:
// Extending from User allows you to have all the User Model functionality
class Student extends User
{
public function mentoria(){
return $this->belongsTo(Mentoria::class)->with('teacher');
}
}
Mentoria 模型:
public function teacher(){
return $this->belongsTo(Teacher::class);
}
public function students(){
return $this->hasMany(Student::class);
}
最后,当您像这样调用对象时,您将从指导中获得所需的所有信息:
Teacher::with('mentorias')->get();
// This will show the Teacher's mentorias and the students in each one
Student::with('mentoria')->get();
// This will show the Student's mentoria and its teacher
Mentoria::with(['teacher', 'students'])->get();
// This will show the teacher and the students for each mentoria
你好,我正在做一个 Laravel 项目,我必须分配一个 Mentorship «Mentoria»,一个 Mentor «Mentor» 和一个学生 «Mentorando»。学生和导师的数据来自用户 table(我使用 Spatie 为他们分配了角色),另一个 table 称为 «Mentoria» 因为存在多对多关系 i创建了名为 «utilizador_mentoria» 的枢轴 table 并具有 ID_Mentor、ID_Mentorando(两者都是来自用户 table 的 FK)和 ID_mentoria(来自 Mentoria table)。我将这两个模型定义为:
用户模型:
protected $casts = [
'email_verified_at' => 'datetime',
];
public function interesses(){
return $this->belongsToMany(AreaInteresse::class, 'utilizador_interesse', 'id_utilizador', 'id_interesse');
}
public function mentorias(){
return $this->belongsToMany(Mentoria::class, 'utilizador_mentoria', 'id_mentoria', 'id_mentorando', 'id_mentor');
}
ps: 我对其他型号有兴趣,工作正常。我的问题是 «mentorias»
Mentoria 模型:
public function users(){
return $this->belongsToMany(User::class, 'utilizador_mentoria','id_mentor','id_mentorando','id_mentoria');
}
有了这个,我试图从所有 Mentorias 获取数据,以及分配给那个 Mentoria 的 Mentor 的数据,但是当我在控制器上执行此代码时,数据来自用户看起来是空的,尽管我的数据库中充满了数据。试了echo测试,只显示Mentoria的数据,应该出现分配给那个MEntoria的Mentor的数据,是空的
来自控制器的代码:
public function mentorias(){
$mentorias = Mentoria::with('users')->get();
echo $mentorias;
return view('admin/mentorias/admin_mentorias', ['mentorias' => $mentorias]);
}
回显的输出
[{"id":2,"titulo":"teste","titulo_en":"test","descricao":"fe","descricao_en":"ewfwe","created_at":"2021-12-28T01:32:10.000000Z","updated_at":"2021-12-28T01:32:10.000000Z","users":[]}]
因为正如我已经说过的,我已经使用了 2 table 的多对多关系数据,但是每个 PK 只有 1 个 FK,而且它工作正常,我不知道为什么不是这样工作的。我已经检查过类似的问题,但是没有运气
编辑:
出于测试目的,我删除了从同一 PK 引用的两个 FK 之一的列,并且我设法工作,但是对于这个附加的 FK,我无法使其工作。我认为问题出在模型中的关系上,但我不知道如何让它工作
我重新排列了模型中的函数,就像现在一样 用户模型:
public function mentorias(){
return $this->belongsToMany(Mentoria::class, 'utilizador_mentoria', 'id_mentor', 'id_mentorando', 'id_mentoria');
}
Mentoria 模型:
public function users(){
return $this->belongsToMany(User::class, 'utilizador_mentoria','id_mentoria','id_mentorando','id_mentor');
我也试过从 main () 中取出 example «id_entorando» 并用 «withPivot» 方法把它放在后面,但还是不行
我不知道我是否正确理解了这个问题,但你的关系不是单一的“多对多”,而是两个“一对多”。最后,我将说明为什么将它们视为两个分离的关系很方便。
首先:如果一个用户可以有多个导师,但一个导师只能有一个导师(我想这是正在发生的事情),那么你应该使用“hasMany/belongsTo”对:
用户模型:
public function mentorias(){
return $this->hasMany(Mentoria::class);
}
Mentoria 模型:
public function user(){
return $this->belongsTo(User::class);
}
其次:完成与导师和学生之间的其他关系的场景:
用户模型:
public function mentorias(){
return $this->hasMany(Mentoria::class);
}
public function mentoria(){
return $this->belongsTo(Mentoria::class);
}
Mentoria 模型:
public function user(){
return $this->belongsTo(User::class);
}
public function mentorandos(){
return $this->hasMany(User::class);
}
mentorias
table 中应该有一个 user_id
列代表导师所属的老师:
Schema::table('mentorias', function (Blueprint $table) {
$table->unsignedInteger('user_id')->nullable();
});
而且 users
table 中还应该有一个 mentor_id
列,代表学生所属的导师:
Schema::table('users', function (Blueprint $table) {
$table->unsignedInteger('mentoria_id')->nullable();
});
第三:用户模型的这种双重表示可能会导致混淆,因为两个不同的对象(教师和学生)正在使用相同的模型但并不意味着同时具有两种关系:不应该指导教师学生不应该领导指导。
为了更好地管理教师和学生并防止混淆,您可以创建额外的模型来继承用户模型并为它们定义关系(而不是用户模型),这样您就可以限制字段和关系对于他们中的每一个。
用户模型:
// No relationships
教师模型:
// Extending from User allows you to have all the User Model functionality
class Teacher extends User
{
public function mentorias(){
return $this->hasMany(Mentoria::class)->with('students');
}
}
学生模型:
// Extending from User allows you to have all the User Model functionality
class Student extends User
{
public function mentoria(){
return $this->belongsTo(Mentoria::class)->with('teacher');
}
}
Mentoria 模型:
public function teacher(){
return $this->belongsTo(Teacher::class);
}
public function students(){
return $this->hasMany(Student::class);
}
最后,当您像这样调用对象时,您将从指导中获得所需的所有信息:
Teacher::with('mentorias')->get();
// This will show the Teacher's mentorias and the students in each one
Student::with('mentoria')->get();
// This will show the Student's mentoria and its teacher
Mentoria::with(['teacher', 'students'])->get();
// This will show the teacher and the students for each mentoria