Laravel 模型附加,包括查询中的整个关系

Laravel 模型附加,包括查询中的整个关系,laravel,eloquent,Laravel,Eloquent,编辑:我能够看到我的回复中包含了哪些关系,但我仍然不知道为什么 在我的客户车型上,我有: protected $appends = [ 'nps', 'left_feedback', 'full_name', 'url' ]; 访问器如下所示: /** * Accessor */ public function getNpsAttribute() { if ($this->

编辑:我能够看到我的回复中包含了哪些关系,但我仍然不知道为什么

在我的
客户
车型上,我有:

protected $appends = [
        'nps',
        'left_feedback',
        'full_name',
        'url'
    ];
访问器如下所示:

/**
     * Accessor
     */
    public function getNpsAttribute() {
        if ($this->reviews->count() > 0) {
            return $this->reviews->first()->nps;
        } else {
            return "n/a";
        }
    }



    /**
     * Accessor
     */
    public function getLeftFeedbackAttribute() {
        if ($this->reviews && $this->reviews->count() > 0 && $this->reviews->first()->feedback != null) {
            return "Yes";
        } else {
            return "No";
        }
    }

    /**
     * Accessor
     */
    public function getFullNameAttribute() {
       return ucwords($this->first_name . ' ' . $this->last_name);
    }


    /**
     * Accessor
     */
    public function getUrlAttribute() {
        $location = $this->location;
        $company = $location->company;
        $account_id = $company->account->id;

        return route('customers.show', ['account_id' => $account_id, 'company' => $company, 'location' => $location, 'customer' => $this]);
       
     }
因此,如果我注释掉
$appends
属性,我会得到我最初想要的响应,而客户不会返回我响应中的所有关系

但我确实希望在我的客户对象上附加这些字段。我不明白为什么它会包括它在响应中使用的所有关系。我将返回特定的字符串

那么,有没有一种方法可以让我的
$appends
不包含它在访问器中使用的所有关系


原始问题:

我正在查询属于客户的评论。我想将客户关系作为审查的一部分,但我不想包括客户关系

$reviews = $reviews->with(['customer' => function($query) {
            $query->setEagerLoads([]);
            $query->select('id', 'location_id', 'first_name', 'last_name');
        }]);
$query->setupergeloads([])在这种情况下不起作用

我尝试了
$query->不带('location')也是,但它仍然被包括在内

我应该注意的是,我在模型上没有填充任何内容的
$with
属性

以下是
查看
模型关系:

    public function customer() {
        return $this->belongsTo('App\Customer');
    }
    public function reviews() {
        return $this->hasMany('App\Review');
    }
    


    // I dont want these to be included
    public function location() {
        return $this->belongsTo('App\Location');
    }

    public function reviewRequests() {
        return $this->hasMany('App\ReviewRequest');
    }
以下是
客户
模型关系:

    public function customer() {
        return $this->belongsTo('App\Customer');
    }
    public function reviews() {
        return $this->hasMany('App\Review');
    }
    


    // I dont want these to be included
    public function location() {
        return $this->belongsTo('App\Location');
    }

    public function reviewRequests() {
        return $this->hasMany('App\ReviewRequest');
    }
在响应中,它将类似于:

'review' => [
 'id'=> '1'
 'customer => [
   'somecol' => 'test',
   'somecolagain' => 'test',
   'relation' => [
      'relation' => [

      ]
   ],
   'relation' => [
       'somecol' => 'sdffdssdf'
    ]
  ]
]

因此,一系列关系最终被加载,我不想要它们。

试试:

$review->with(‘customer:id,location_id,first_name,last_name’)->get();
或:


正如您在对主要问题的一次评论中所说的,您得到的是由于附加的访问器而产生的关系

让我告诉您应该如何做(我将复制粘贴您的代码并简单地编辑一些部分,但您仍然可以复制粘贴我的代码并将其放置在您的代码中,并且将以相同的方式工作,但防止添加关系),然后让我解释为什么会发生这种情况:

/**
*存取器
*/
公共函数getNpsAttribute(){
如果($this->reviews()->count()>0){
返回$this->reviews()->first()->nps;
}否则{
返回“不适用”;
}
}
/**
*存取器
*/
公共函数getLeftFeedbackAttribute(){
返回$this->reviews()->count()>0&&
$this->reviews()->first()->feedback!=null
“是的”
:“没有”;
}
/**
*存取器
*/
公共函数getFullNameAttribute(){
返回ucwords($this->first\u name.'.$this->last\u name);
}
/**
*存取器
*/
公共函数getUrlAttribute(){
$location=$this->location()->first();
$company=$location->company;
$account\u id=$company->account->id;
返回路线('customers.show',['account\u id'=>$account\u id',company'=>$company',location'=>$location',customer'=>this]);
}
如您所见,我已将任何
$this->relationship
更改为
$this->relationship()->first()
$this->relationship->get()

如果您以
$this->relationship
的形式访问任何模型的关系,它会将其添加到渴望加载(已加载)中,因此它会真正获取关系数据并将其存储在模型的数据中,这样下次您再次执行
$this->relationship
时,它就不必再转到数据库并再次查询

因此,为了防止这种情况,您必须以
$this->relationship()
的形式访问关系,这将返回一个查询生成器,然后您可以执行
->count()
->exists()
->get()
->first()
或任何其他有效的查询生成器方法,但是,作为查询生成器访问关系将阻止获取数据并将其存储到模型中(我知道先执行
->get()
->first()
将获取数据,但您不是直接通过模型获取数据,而是通过查询生成器关系获取数据,这是不同的)

这样可以防止在模型上存储数据时出错,从而给您带来问题

您还可以使用,它用于将模型或集合映射到所需的输出


最后一件事,如果您可以使用
$this->relation()->exists()
而不是
$this->relation()->count()>0
,这将有助于更快地完成此操作,大多数情况下,任何数据库在查看数据是否存在(
count>=1
)时都比实际计算它拥有的所有条目快,因此,如果将
一起使用,它将不会急于加载关系的关系,除非您使用('relation1.relation2')
之类的操作,否则它将加载两个关系(关系的关系)。你在执行什么,让你说“它渴望加载关系的关系”?它没有这样做。请共享控制器或返回对象的人,因为可能存在问题。@matiaslauriti我已编辑了我的问题。它似乎来自
Customer
模型上的
$append
,该模型包含所有关系,因为它们在访问器方法中使用。你能帮我吗?是的,我能帮你,你说的是对的,让我发布一个答案来尝试帮助你。难以置信的答案和解决方案,谢谢!这对我帮助很大,让我更好地理解。我已经重构了我的模型,停止使用
->relation
并切换到
->relation()->first()
太棒了,这很有帮助!!!