【问题标题】:Illuminate Eloquent return null relation on a relation returning different objectsIlluminate Eloquent 在返回不同对象的关系上返回空关系
【发布时间】:2017-01-29 20:37:06
【问题描述】:

我在 Illuminate 中有一个对象,它的关系可以根据主对象的属性返回不同的对象

public function relation(){
    switch($this->type){
        case "type_1":
            return $this->belongsTo('\Models\Type1', 'idElement');
            break;
        case "type_2":
            return $this->belongsTo('\Models\Type2', 'idElement');
            break;
        default:
            return null;
    }
}

当执行“default”部分时,这会产生“Relationship method must return an object of type Illuminate\Database\Eloquent\Relations\Relation”的错误。

我也无法实例化 new Illuminate\Database\Eloquent\Relations\Relation(),因为它是一个抽象类。

我可以创建一个空表并返回与该空表的关系,该关系将始终返回一个空值,但这不是解决方案。

如何在默认选项中返回空关系?

更新:

我已经改成使用多态关系,但现在的问题是:如何将多态关系设置为可选关系?

Relation::morphMap([
    'type_1' => \App\Models\Type1::class,
    'type_2' => \App\Models\Type2::class
]);

....

public function relation(){
    return $this->morphTo(null, 'type', 'idElement');
}

【问题讨论】:

  • 你好 Hilmi,我没有使用 Laravel,只使用 Slim 框架项目中的 Illuminate 组件。
  • 这种关系会破坏 Eloquent 的急切加载功能。我认为您应该确定类型并从模型而不是单个模型加载不同的关系。我不确定(我不知道你的情况),但多态关系也可能起作用。
  • 看来多态关系是我要找的,我去试试看。
  • 好吧,我已经能够成功使用多态关系,但是当关系是可选的时,我面临同样的问题:github.com/laravel/framework/issues/1450

标签: laravel eloquent illuminate-container


【解决方案1】:

我建议创建一个存根关系类,并在需要返回始终为空(或固定)的集合时使用它。

<?php

namespace App;

use Illuminate\Database\Eloquent\Relations\Relation;
use Illuminate\Database\Eloquent\Collection;

/**
 * Stub relationship
 */
class EmptyRelation extends Relation
{
    public function __construct() {}
    public function addConstraints() {}
    public function addEagerConstraints(array $models) {}
    public function initRelation(array $models, $relation) {}

    public function match(array $models, Collection $results, $relation)
    {
        return $models;
    }

    public function getResults()
    {
        return new Collection();
    }
}

然后在您的默认部分中执行以下操作:

return new \App\EmptyRelation();

【讨论】:

    【解决方案2】:

    嗯..这可能不是最好的选择,但有效

    public function relation(){
        switch($this->type){
            case "type_1":
                return $this->belongsTo('\Models\Type1', 'idType1');
                break;
            case "type_2":
                return $this->belongsTo('\Models\Type2', 'idType2');
                break;
            default:
                return $this->hasOne('\Models\ThisModel', 'id','id')->where('id','<',0 );//Assuming you have an id autoincrement field that starts in 1  in your table, 
        }
    }
    

    这将返回一个空集合,我不确定这是否是您要查找的内容

    【讨论】:

    • 是的,它应该可以工作,但我不想在数据库中查询我知道不存在的对象。
    • 这将执行一个无意义的查询
    猜你喜欢
    • 1970-01-01
    • 2014-06-26
    • 1970-01-01
    • 2020-09-09
    • 1970-01-01
    • 1970-01-01
    • 2018-03-20
    • 2014-07-09
    相关资源
    最近更新 更多