Laravel-多对一多态关系

Posted

技术标签:

【中文标题】Laravel-多对一多态关系【英文标题】:Laravel-Many-to-one Polymorphic relationship 【发布时间】:2016-01-26 23:59:14 【问题描述】:

我正在使用 laravel 5.1。场景如下(这是一个例子,真实场景和这个例子类似)

我有 3 个模型

    学院 学生 老师

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

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

我想在 laravel 中建立这些表之间的关系。 一种方法是在学生和教师表上放置一个 college_id 外键。但在我的情况下,这个外键很多时候都是空的。因此,我不想在 3-4 个表中包含大部分为空值的单独列,而是想探索为 College 表提供多态关系的选项。

这是我尝试过的: laravel 文档(下面的链接)中给出的示例描述了一对多的关系,而我的场景更多的是多对一的关系。

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

如示例中所示,College 表中包含collegeable_id 和collegeable_type 列无法满足我的要求,因为大学可以包含许多学生/教师,因此我创建了一个数据透视表:

Schema::create('collegeables', function (Blueprint $table) 
        $table->integer('college_id')->unsigned();
        $table->integer('collegeable_id')->unsigned();
        $table->string('collegeable_type');
    );

我有以下型号

大学模特:

    namespace App;

use Illuminate\Database\Eloquent\Model;

class College extends Model

    public function students()
    
        return $this->morphedByMany('App\Student', 'collegeable');
    

学生模型:

    namespace App;

use Illuminate\Database\Eloquent\Model;

class Student extends Model

    public function college()
    
        return $this->morphOne('App\Colleges', 'collegeable');
    

通过这种安排,我可以像这样使用 College 模型实例来存储学生

$college = \App\College::find(1);
$student = new \App\Student;
$student->name = 'John Doe';
$college->students()->save($student);

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

public function index()
    
        return \App\Student::find(1)->college;
    

SQLSTATE[42S22]:找不到列:1054 未知列 'colleges.collegeable_id'

这是意料之中的,因为我认为 morphOne 可以处理表中的列。 如果我将学生模型中的 morphOne 函数更改为 morphToMany,代码开始工作,我也可以检索值。但这使这种关系成为多对多的关系,这又不是我想要的。

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

任何帮助将不胜感激。谢谢。

【问题讨论】:

我认为你把一切都搞砸了,你不需要多态关系。 @MikelBitson,谢谢。我在一对一和一对多关系上使用了 morphOne-morphTo 和 morphMany-morphTo 关系函数。在这些场景中使用了collegeable 函数,但它不适用于我的场景。 @fico7489,是的,我真的只是在规划阶段,我只是想知道这是否可能。我意识到我可以简单地在学生和教师表上使用外键。谢谢。 【参考方案1】:

这里没有理由使用多态关系。相反,只需在 studentsteachers 表上的 colleges 表中添加一个外键。像这样:

colleges
    id
    name

teachers
    id
    name
    college_id

students
    id
    name
    college_id

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

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 风格的网站。有客户和项目,您希望对两者都有评论。在这种情况下,您可以将 Comments 设为多态关系,因为 Comments 属于单个客户或单个项目,但不能同时属于两者。

你们的关系正好相反。在您的情况下,学生和教师属于一所大学。如果您要遵循上一个示例的模式,那么一所大学将属于单个学生或教师。

【讨论】:

感谢您的澄清。你的最后一个陈述正是我正在寻找的,即多态关系不适用于我的场景。我打算使用您上面建议的相同外键方法,但只是想知道多态关系是否有效。无论如何,我的场景不符合多态一对多关系的特殊原因吗? @SaurabhMisra 查看我刚刚所做的编辑

以上是关于Laravel-多对一多态关系的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 雄辩的关系多对一不起作用

laravel 模型中的一对一,一对多,多对多的关联

Hibernate,关系映射的多对一单向关联多对一双向关联一对一主键关联一对一外键关联多对多关系关联

laravel ORM 一对一 一对多 多对多 原生的MYSQL怎么写

关于JPA一对一,一对多(多对一),多对多的详解

Hibernate多对一,多对多的表映射关系