2017-06-22 47 views
2

我有我的EloquentModels看起来像这样内的各种关系:Laravel雄辩 - 不运行关系查询,如果列值为NULL或0

public function main_image() 
{ 
    return $this->hasOne(Media::class, 'id', 'main_image_id'); 
} 

然而,它会运行一个SQL查询,如果main_image_id是空或0,所以我结束了一些查询的是这样的:

select * from `media` where `media`.`id` is null and `media`.`id` is not null limit 1 

这显然不会返回任何东西,但还是浪费资源。有什么方法可以自动检查吗?

目前我所做的是有一个方法,如hasMainImage(),检查main_image_id是不是空的,但不是0,但很多目前的系统已经使用的关系,我想知道如果我可以添加检查关系方法本身?

我曾尝试添加一个检查到它并返回null如果该列没有实际值,但我有Exception它必须返回一个关系对象。或者,如果我试图贪婪加载它,我收到以下错误:

Call to a member function addEagerConstraints() on null

public function main_image() 
{ 
    if (!$this->main_image_id) { 
     return null; 
    } 

    return $this->hasOne('App\Modules\Media\Models\Media', 'id', 'main_image_id'); 
} 

感谢您的帮助!

编辑: 一个或许更明显的例子:

$page = Page::find(1); 
var_dump($page->main_image); // This will run a query as shown above that is guaranteed to return nothing 
// Since at this point system knows that $page->main_image_id is 0 or null, I would like to use that to not run the query and automatically set $page->main_image to null 
+0

做一个'with'使用额外的资源。你首先不应该这样做,不要到处做,然后试着绕过它。 – apokryfos

+0

'with'并不是随处可见,只有一次加载多个模型。当只加载单个实例时,不会使用'with',并调用像'$ page-> main_image'这样的调用。这些是我试图在这里优化的电话 – Giedrius

+0

如果你这样做,没有额外的好处。连接将以任何方式发生,它只会返回更少的东西。我当然假设你在这里有一对一的关系。 – apokryfos

回答

0

你在错误的顺序声明你的关系,Eloquent documentation是清楚这一点。

本身没有意义的实体(没有它的“父”,你可以说)应该包含“belongsTo”关系(正如文档中所说的那样)。

为了演示可以说你有用户模型,并且你有很多关于该用户的细节,所以你创建了详细模型。

现在用户模型应该有详细的关系:

public function detail() { 
    return $this->hasOne('App\Detail', 'user_id', 'id'); //you can see the difference here from your code sample, you have 2nd and 3rd parameter reversed 
} 

和细节模型应该有用户关系:

public function user() 
{ 
    return $this->belongsTo('App\User'); 
} 
+0

这不是我目前的结构。我有'Page'模型和'Media'模型。 “媒体”模型是一个不包含任何其他模型的自包含模型(因为它可以被不同模型和模型实例多次使用)。 'Page'有一个'main_image'方法(定义在quetstion中)定义了与'Media'的关系。如果我事先知道它不会返回任何内容,我不想运行SQL查询。我不确定在'Media'模型中如何定义'belongsTo'来解决这个问题?我不需要以任何方式从“媒体”实例中访问任何其他模型。 – Giedrius

+0

所以你使用多态关系吗? – Kyslik

+0

不是这种情况。 'Page' Model可以将与其相关的一个'Media'作为'main_image',但是,相同的'Media'模型可以作为'main_image'与其他页面相关联,并且许多其他模型可以作为不同种类的图像。因此'Page'“有一个”Media对象,它在'pages'表中被引用为'main_image_id'。我想知道我是否应该在这里使用'belongsTo'关系?而且这是否会在运行查询中产生任何影响?我认为它会运行我想摆脱任何方式的SQL查询,因为那里可能有一个0。 – Giedrius