【问题标题】:Laravel attribute not working as expectedLaravel 属性未按预期工作
【发布时间】:2020-04-26 23:20:19
【问题描述】:

在当前的应用程序中,有一个模型Part和一个模型Supplier。每个零件都有一个供应商。

    public function supplier()
    {
        return $this->belongsTo(Supplier::class);
    }

我添加了一个访问器来获取供应商的名称。

如果我返回整个数据集,我会得到供应商:

    public function getSupplierNameAttribute()
    {
        return $this->supplier;
    }
    "supplierName": {
        "id": 1,
        "uuid": "37e3a715-09d3-4fac-ae88-8f12e63fe79c",
        "name": "Laserteam",
        "street": "8602 Dessie Tunnel",
        "zip": "15869",
        "city": "New Clementview",
        "email_send_type": null,
        "active": 0,
        "created_at": "2020-01-09 09:46:02",
        "updated_at": "2020-01-09 09:46:02",
        "deleted_at": null,
        "action": "",
        "activeLabel": "<span class='badge badge-secondary'>Inaktiv<\/span>"
    },

如果我尝试只获取名称(我最终需要的),则会出现错误:

    public function getSupplierNameAttribute()
    {
        return $this->supplier->name;
    }
ErrorException: Trying to get property 'name' of non-object in file /gopanel/sites/7industry_net/public/7time/app/Models/Part/PartAttribute.php on line 48

如果我以这种方式尝试,它会起作用:

    public function getSupplierNameAttribute()
    {
        return $this->supplier['name'];
    }

为什么return $this-&gt;supplier-&gt;name; 不起作用?

【问题讨论】:

  • 只是一个想法,但尝试在关系函数上添加foreignKey。 : return $this->belongsTo(Supplier::class,'foreignKey');
  • 看起来应该可以了。你确定你在任何地方都没有toArray 吗?或者您曾经在某个地方拥有它并且尚未重新加载 tinker(如果您正在使用 tinker)?
  • 看起来很傻,但是尝试$g = $this-&gt;supplier; 然后return $g-&gt;name 如果在返回之前失败dd($g); 看看里面有什么。

标签: laravel eloquent laravel-6


【解决方案1】:

很难说这里可能是什么问题,但是:

  1. 确保您的模型中没有 supplier
  2. 确保你不要使用supplier 作为数据库列名,或者你不要在某处做这样的事情

    $this->supplier = $this->supplier->toArray();
    

似乎supplier 属性在某处变成了数组,这就是为什么一种表示法有效而另一种无效的原因。

【讨论】:

    【解决方案2】:

    我不太确定那里发生了什么;如果您有 supplier 关系,那么访问属性应该延迟加载关系。

    或者,您可以尝试以下语法:

    public function getSupplierNameAttribute()
    {
        $this->loadMissing('supplier');
    
        return $this->getRelation('supplier')->name;
    }
    

    但是,我会避免像这样定义访问器。如果您说,检索一组部件然后在每个部件上调用 $part-&gt;supplier_name 而不急切加载 supplier 关系,这可能会导致 N+1 问题。

    就个人而言,如果我要访问归因于我更喜欢​​通过关系(即$part-&gt;supplier-&gt;name)的关系,那么我需要急切加载的任何关系都会显示给我。

    【讨论】:

    • 我使用来自 webix 的数据表。因此我需要第一层的供应商名称。也许我稍后会用 api 资源来做。​​
    【解决方案3】:

    试试这个代码

    public function getSupplierNameAttribute()
    {
        return $this->supplier->name ?? 'supplier not exists';
    }
    

    【讨论】:

    • 我有一个Part 没有supplier_id。所以代码有效,但我必须先询问是否存在供应商关系。
    • @Peter 但它如何解决您的问题?你有问题地写道,对于你有供应商的每条记录,所以我相信它没有帮助。它只是隐藏问题而不是解决它。
    • 我误以为每个零件都有供应商。这是基本错误!
    猜你喜欢
    • 1970-01-01
    • 2021-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-05
    • 2011-08-28
    • 1970-01-01
    • 2021-09-21
    相关资源
    最近更新 更多