首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >多对一多态关系

多对一多态关系
EN

Stack Overflow用户
提问于 2015-10-27 14:10:31
回答 2查看 5.4K关注 0票数 4

我用的是拉拉5.1。场景如下(这是一个示例)。真实的场景类似于这个例子)

我有三个模特

  1. 大学
  2. 学生
  3. 教师

一所大学可以有很多学生,但一个学生只能属于一所大学。

一所大学可以有许多教师,但一名教师只能属于一所大学。

我想在这两张桌子之间建立关系。其中一种方法是在“学生和教师”表上放置一个college_id外键。但是在我的例子中,这个外键很多时候都是空的。因此,与其在3-4个表中使用多为空值的单独列,我还想探讨为College表建立多态关系的选择。

,这就是我尝试过的:,在laravel (下面的链接)中给出的例子,描述了一对多的关系,而我的场景则是多到一的关系。

http://laravel.com/docs/5.1/eloquent-relationships#polymorphic-relations

如示例中所示,在College表中包含collegeable_id和collegeable_type列并不能满足我的要求,因为一所大学可以容纳许多学生/教师,因此我创建了一个枢轴表:

代码语言:javascript
复制
Schema::create('collegeables', function (Blueprint $table) {
        $table->integer('college_id')->unsigned();
        $table->integer('collegeable_id')->unsigned();
        $table->string('collegeable_type');
    });

我有以下的模型

大学模式:

代码语言:javascript
复制
    namespace App;

use Illuminate\Database\Eloquent\Model;

class College extends Model
{
    public function students()
    {
        return $this->morphedByMany('App\Student', 'collegeable');
    }
}

学生模式:

代码语言:javascript
复制
    namespace App;

use Illuminate\Database\Eloquent\Model;

class Student extends Model
{
    public function college()
    {
        return $this->morphOne('App\Colleges', 'collegeable');
    }
}

有了这样的安排,我就可以像这样使用大学模型实例来存储学生

代码语言:javascript
复制
$college = \App\College::find(1);
$student = new \App\Student;
$student->name = 'John Doe';
$college->students()->save($student);

但是,当我试图使用下面指定的学生模型实例检索大学模型实例时,它会给出一个错误:-

代码语言:javascript
复制
public function index()
    {
        return \App\Student::find(1)->college;
    }

SQLSTATE42S22:未找到列: 1054列“colleges.collegeable_id”

我认为,这在某种程度上是预期的,因为morphOne可以处理表中的列。如果我将学生模型中的morphOne函数更改为morphToMany,代码就会开始工作,我也能够检索值。但这使得这种关系对许多人来说,这也不是我想要的。

因此,我的问题是:-它们是我可以在学生模型中使用的morphSomething函数吗?能够在保持一对多关系的同时为学生的大学检索值吗?

任何帮助都会很感激的。谢谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-10-27 15:33:02

这里没有理由使用多态关系。相反,只需在您的colleges表和teachers表中添加一个外键即可。如下所示:

代码语言:javascript
复制
colleges
    id
    name

teachers
    id
    name
    college_id

students
    id
    name
    college_id

然后,您的模型可以使用belongsTo()hasMany()关系,如下所示:

代码语言:javascript
复制
class College extends Model {
    public function students() {
        return $this->hasMany(App\Student::class);
    }

    public function teachers() {
        return $this->hasMany(App\Teacher::class);
    }
}

class Teacher extends Model {
    public function colleges() {
        return $this->belongsTo(App\College::class);
    }
}

class Student extends Model {
    public function colleges() {
        return $this->belongsTo(App\College::class);
    }
}

多态一对多的关系与这种关系相反,在这种关系中,您有一个只能与单个记录相关的模型,但该记录可以是许多不同的模型。

编辑:为了进一步解释为什么这里不需要多态关系,让我们看一下需要多态关系的地方。假设你有一个简单的CRM风格的网站。这里有客户和项目,您希望对两者都有评论。在这种情况下,您将使注释成为多态关系,因为注释属于单个客户或单个项目,而不是两者兼有。

你们的关系正好相反。在你的例子中,学生和教师都属于一所大学。如果你要遵循上一个例子的模式,一所大学应该属于一个学生或教师。

票数 10
EN

Stack Overflow用户

发布于 2022-08-24 21:21:52

我有一个类似的需求,并设法以另一种方式即兴发挥,利用变形的桌子结构。

您需要一个大学类才能成为数据透视(https://laravel.com/docs/9.x/eloquent-relationships#defining-custom-intermediate-table-models)

然后魔法:

代码语言:javascript
复制
public function college(){
    return $this->hasOneThrough(Colleges::class,
        Collegeable::class,
        'collegeable_id',
        'id',
        'id',
        'college_id',
    );
}

学院的枢轴类上:

代码语言:javascript
复制
namespace App\Models;

use Illuminate\Database\Eloquent\Relations\Pivot;

class Collegeable extends Pivot
{
    protected $table = 'collegeables';
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33370264

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档