首页 > 解决方案 > laravel eloquent:Eloquent 关系需要在没有数据的时候返回一些东西,而不是返回 null 对象

问题描述

我的产品型号上有这种关系。

public function productInventory(){
        return $this->hasOne('App\Models\Ecommerce\Inventory', 'product_id')->where('is_deleted', 0);
}

有时,我可能没有在我的库存表中插入该特定产品。因此,这种关系仍然在视图中起作用,但会尝试获取 productInventory->price ,这将引发错误,cannot get price of null object。所以,我现在已经做到了,这只是一件简单的事情。但是计数是1或大于1,因为还有其他产品。那么,对于库存表中没有数据的特定产品,我如何才能只返回 null 呢?

public function productInventory(){
        $has_inv = Inventory::where('product_id',$this->id)->where('is_deleted', 0)->count();        
        if($has_inv < 1){
            return null;
        }
        return $this->hasOne('App\Models\Ecommerce\Inventory', 'product_id')->where('is_deleted', 0);
    }

标签: phplaravellaravel-5eloquent

解决方案


首先,方法 productInventory() 必须返回关系。某些记录没有连接的库存并不重要。此方法必须返回关系,仅此而已......将此返回与数据库的实际状态(“对于此特定产品没有库存”)混淆,恕我直言。

因此,如果您的问题在于视图,当没有库存时您会收到错误,更好的解决方案是:

如果有可用的对象,请检查视图,然后才检查该对象的价格属性。

你可以用类似的东西来检查它...

@if(is_null($productInventory)) 
 {{$productInventory->price}}
@endif

顺便说一句,这是代码示例,而不是实际的真实代码。但它让你知道在哪里解决这个问题。

因为,您在错误的地方解决了这个问题。关系方法不是地方,恕我直言。

如果你在很多视图中使用它,你必须优化你的视图结构(通过使用包含!),而不是把问题移到代码中的不同位置。

为您经常使用的视图代码创建一个包含,并包含类似以下内容:

@include('product_incventory_price_data')

关于 Blade 中的包含

让我们<head>在您的网页中使用您的代码示例。您可以将其添加到所有单独的网页(您的视图文件)。让我们看看两种不同的观点 (A en B)

文件:view_a.blade.php

<html>
<head>
    <meta charset="utf-8">
    <title>{{$page->title}}</title>
    <meta name="description" content="{{$page->description}}">
    <meta name="keywords" content="{{$page->keywords}}">
</head>
<body>
...stuff for view A
</body>
</html>

文件:view_b.blade.php

<html>
<head>
    <meta charset="utf-8">
    <title>{{$page->title}}</title>
    <meta name="description" content="{{$page->description}}">
    <meta name="keywords" content="{{$page->keywords}}">
</head>
<body>
...stuff for view B
</body>
</html>

更好的解决方案:将所有<head>代码移动到不同的文件(在视图/共享等文件夹中)。并将该文件包含在 A 和 B 视图中。

共享/head.blade.php

<head>
    <meta charset="utf-8">
    <title>{{$page->title}}</title>
    <meta name="description" content="{{$page->description}}">
    <meta name="keywords" content="{{$page->keywords}}">
</head>

view_a

<html>
@include('shared/head')
<body>
...stuff for view A
</body>
</html>

view_b

<html>
@include('shared/head')
<body>
...stuff for view B
</body>
</html>

您可以使用各种视图代码来执行此操作。此外,您的产品价格信息可以移动到一个地方并使用 @include()... 在多个其他视图中使用。

您通过控制器传递给视图的数据也会传递给包含文件。不用担心.... :-)

关于视图和子视图的 Laravel 文档


推荐阅读