【问题标题】:Lazy eager loaded relationship missing in toArray()toArray() 中缺少延迟加载的关系
【发布时间】:2019-09-19 02:26:51
【问题描述】:

Laravel 5.8

我懒惰地加载具有与 crmaccount-object 一对一关系的相关客户的用户

模型正在工作,因此当我检索预先加载的实体时,它会显示所有嵌套关系。

一行之后,我对该对象使用“toArray()”方法,但输出缺少第三级关系。

关于“crmaccount”模型的唯一可能某种特殊之处在于它包含一个必须转换为 json 的列。

知道这里发生了什么吗?

所有这些都发生在中间件中。如果我使用 with 或 load 没有区别。

public function handle($request, Closure $next)
{
    $UserData = \Auth::user();
    if($UserData){
        $User = \App\Login::with(['role','customer','customer.crmaccount'])->find($UserData->id);
        dump($User);
        dd($User->toArray());


        $UserData['isAdmin'] = false;
        if($UserData['role']['name'] === 'Admin'){
            $UserData['isAdmin'] = true;
        }
        $request->request->add(['UserData' => $UserData]);
    }

    return $next($request);
}

登录

<?php

namespace App;

use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;

class Login extends Authenticatable{
    use Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'email', 'password','customer_id','role_id'
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];

    /**
     * The attributes that should be cast to native types.
     *
     * @var array
     */
    protected $casts = [
        'email_verified_at' => 'datetime',
    ];
    /* */
    public function Role(){
        return $this->belongsTo('App\Role');
    }
    public function Customer(){
        return $this->belongsTo('App\Customer');
    }
    /**
     * [hasOpportunities Ruft alle Opportunities des Users ab. Da diese lediglich zwei Entitäten weiter sind, kann anstatt von dot-notated Lazy-Load auch die hasManyThrough-ORM-Methode genutzt werden]
     * @return [hasManyThrough-Relation] [Die hasManyThrough-ORM-Beziehung]
     */
    public function hasOpportunities(){
        return $this->hasManyThrough(
            'App\Opportunity',
            'App\Customer',

            'id',
            'customer_id',
            'customer_id'
        );
    }
    /**
     * [hasSalesreps Ruft alle SalesReps des Users ab. Da diese lediglich zwei Entitäten weiter sind, kann anstatt von dot-notated Lazy-Load auch die hasManyThrough-ORM-Methode genutzt werden]
     * @return [hasManyThrough-Relation] [Die hasManyThrough-ORM-Beziehung]
     */
    public function hasSalesreps(){
        return $this->hasManyThrough(
            'App\Salesrep',
            'App\Customer',

            'id',
            'customer_id',
            'customer_id'
        );
    }
}

客户

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Customer extends Model{
    public $timestamps = false;

    protected $visible = ['id','name'];

    protected $fillable = ['name'];


    public function crmaccount(){
        return $this->hasOne('App\Crmaccount');
    }

    public function Salesreps()
    {
        return $this->hasMany('App\Salesrep');
    }

    public function Prospects()
    {
        return $this->hasMany('App\Prospect');
    }

    public function Trees()
    {
        return $this->hasMany('App\Salesreptrees');
    }

    public function Opportunities()
    {
        return $this->hasMany('App\Opportunity');
    }

    public function User()
    {
        return $this->hasMany('App\Login');
    }
}

CRM 帐户

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Crmaccount extends Model{
    public $timestamps = false;
    protected $visible = ['id','name','crm_system','customer_id','crm_api_config'];
    protected $fillable = [
        'name','crm_system','customer_id','crm_api_config'
    ];
    protected $casts = [
        'crm_api_config' => 'array'
    ];
    public function customer(){
        return $this->belongsTo('App\Customer');
    }
}

【问题讨论】:

  • 试试with(['Role','Customer', 'Customer.crmaccassasad']);省略中间关系可能是个问题。还要注意,关系是camelCase,所以Role应该是roleCustomer应该是customercrmaccassasad 很好(但可能更清楚)。另外,你需要使用-&gt;toArray()吗? $request-&gt;request-&gt;add() 不接受 object 吗?
  • 感谢您的回复。我弄乱了导致“crmaccassasad”的列名;-) 这些命名约定到底是在哪里说明的?我会更新我的模型和报告。
  • 整个文档; public function posts()public function comments() 等。可以是 camelCasesnake_case,但要避免大写(型号名称为 StudlyCase 等),但它们只是约定;它们不会引起问题。那么,crmaccassasadcolumn 还是 relationship?看起来应该是第一张图片中的crmacc
  • 我什么也不想说 :P 尝试将crmaccount 添加到protected $visible;看看是否包括在内。如果该属性影响关系,我不是 100%,但我认为确实如此。
  • 你成就了我的一天 :) 我也有这样的想法,但就像“哦,他们会在标记为红色的文档中说明这一点”。它在将方法名称或“属性”添加到“母亲”的可见数组后起作用,在本例中为“客户”。请再次将您的评论作为帖子发布,这样我就可以投票并标记为解决方案。

标签: laravel laravel-5 eloquent


【解决方案1】:

在每个模型上,都有一个 protected $visible = [];protected $hidden = [] 属性。这些控制在模型转换为objectarrayjson 时可用的属性。这包括 relationships,因为 Laravel 在内部将它们转换为属性,因此从 visible 中省略它们,或者将它们包含在 hidden 中将导致它们不可用。

Customer.php:

protected $visible = ['id','name'];

由于crmaccount 不在该数组中,因此只有idname 可用。只需在数组中添加crmaccount 即可处理:

protected $visible = ['id','name', 'crmaccount'];

或者,使用hidden 明确设置您不想显示的属性,如果通过-&gt;with() 加载,relationship 将默认显示。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-11-10
    • 2019-07-11
    • 2019-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多