模型内的条件关系

时间:2020-06-28 20:59:41

标签: php laravel

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

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列是否等于控制器来有条件地返回一个关系,尽管检查不起作用并且它仅返回第二个关系,即使type是{ {1}}

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

2 个答案:

答案 0 :(得分:1)

$this将在您的关系方法中可用,但是,如果您渴望加载unit关系(而不是懒惰的渴望加载),type将是null。这是因为建立关系type时不会设置query属性。

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

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


解决方案

您拥有的东西很适合Polymorphic relationship

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

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

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

AppServiceProvider

答案 1 :(得分:0)

可以在模型类上使用$this,并且您的关系可能会以某种方式起作用。

但是我建议您改用Polymorphic Relationships

/**
 * Get the unit.
 */
public function unit()
{
    return $this->morphTo(__FUNCTION__, 'type', 'unit_id');
}

Eloquent使用type列来确定在访问单位关系时要返回的父模型的“类型”,它将是App\Models\FMS\ControllerApp\Models\FMS\Unit

要使用自己的自定义类型,必须在morphMap的启动功能中注册AppServiceProvider

use Illuminate\Database\Eloquent\Relations\Relation;

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