Laravel-Many-to-one多态关系

时间:2015-10-27 14:10:31

标签: php laravel one-to-many laravel-5.1 polymorphic-associations

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

我有3个模特

  1. 学院
  2. 学生
  3. 教师
  4. 一所大学可以有很多学生但学生只能拥有一所大学。

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

    我想在laravel中建立这些表之间的关系。 其中一种方法是在Students and Teachers表中放置 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 = \App\College::find(1);
    $student = new \App\Student;
    $student->name = 'John Doe';
    $college->students()->save($student);
    

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

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

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

    这是一种预期,因为morphOne可以与表格中的列一起使用。 如果我将学生模型中的morphOne函数更改为morphToMany,代码将开始工作,我也能够检索值。但是,这使得这种关系变得很多,而这又不是我想要的。

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

    任何帮助都会非常感激。感谢。

1 个答案:

答案 0 :(得分:6)

这里没有理由使用多态关系。相反,只需在collegesstudents表的teachers表中添加外键即可。像这样:

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

你的关系恰恰相反。在您的情况下,学生和教师属于大学。如果你要遵循上一个例子的模式,那么一所大学就属于一个学生或老师。

相关问题