首页 > 解决方案 > 模型内的条件关系

问题描述

我有一个包含一unit_id列和一type列的模型,2 行可以有相同unit_id但不同type的 s。我在模型中有一个方法

public function unit()
{
  if ($this->type == 'controller') {
    return $this->belongsTo('App\Models\FMS\Controller', 'unit_id', 'id');
  } else {
    return $this->belongsTo('App\Models\FMS\Unit', 'unit_id', 'id');
  }
}

这意味着根据type列是否等于控制器有条件地返回关系,尽管检查不起作用并且它只返回第二个关系,即使typecontroller

我知道无法$this在模型中访问,所以我还有其他方法可以解决这个问题吗?

标签: phplaravel

解决方案


$this将在您的关系方法中可用,但是,如果您急切加载unit关系(而不是延迟急切加载) type,则null. 这是因为在type建立关系时不会设置属性query

如果您在加载初始类后加载关系,则您拥有的代码应该可以工作。

如果您在 Eloquent 集合上使用load(),那么我相信它将使用type集合中第一个模型上的任何一个。


解决方案

你所拥有的很适合多态关系

将您的unit()方法更改为:

public function unit()
{
    return $this->morphTo('unit', 'type', 'unit_id');
}

与 Laravel 的多态关系的默认设置是将类的完全限定名称空间作为类型,但由于这种情况下的类型只是controller或者unit你需要告诉 Laravel 如何将这些单词映射到相关类. 为此,您可以使用Relation::morphMap()
boot()AppServiceProvider(公平地说,它可以是任何服务提供商)的方法中添加以下内容:

Relation::morphMap([
    'unit'       => 'App\Models\FMS\Unit',
    'controller' => 'App\Models\FMS\Controller',
]);

推荐阅读