Laravel withOnly不限制查询

sh7euo9m  于 2023-10-22  发布在  其他
关注(0)|答案(1)|浏览(115)

下面是User::class

class User extends Authenticatable
{
    /* ........ */

    protected $with = ['subscription', 'photo'];

    public function subscription(): HasOne
    {
        return $this->hasOne(Subscriptions::class, 'id', 'subscription_id');
    }
    
 
    public function photo(): HasOne
    {
        return $this->hasOne(Files::class, 'id', 'photo_file_id');
    }
}

通过使用$with,当查询User::class时,总是加载关系subscriptionphoto
但是,有时候我想避免这种关系。该文档说:
如果你想在一个查询中覆盖$with属性中的所有项,你可以使用withOnly方法:
考虑到这一点,我执行了以下查询:

$notifications = \App\Models\Notifications::withOnly('fromuser')
    ->where('to_user_id', auth()->user()->id)
    ->limit(15)
    ->orderBy('id', 'DESC')
    ->get();

然而Laravel的搜索栏显示subscriptionphoto关系都被加载了。同样,如果我输出$notifications->toArray(),关系也会显示出来。
Notifications::class非常简单:

class Notifications extends Model
{
    /* ..... */
    
    public function fromuser(): HasOne
    {
        return $this->hasOne(User::class, 'id', 'from_user_id');
    }

    public function touser(): HasOne
    {
        return $this->hasOne(User::class, 'id', 'to_user_id');
    }
}

我错过了什么?

编辑:我知道我可以做到:

\App\Models\Notifications::with(['fromuser' => function($query)
{
    $query->without(['subscription', 'photo']);
}])

但我想避免这种情况,因为:
1.我叫User::class是几百个地方
1.我以后可能会添加更多的关系
如果不可能只做->withOnly,我可能会忘记使用$with属性。

ukxgm1gy

ukxgm1gy1#

我觉得你没那么多选择:您可以在通知中创建作用域

class Notifications extends Model
{

    public function scopeWithUser($query, $relations = [])
    {
        return $query->with(['fromuser' => fn($query) => 
            empty($relations)
                ? $query->setEagerLoads([])
                : $query->withOnly($relations)
        ]);
    }
}

然后又道:

Notifications::withUser()->get()

或者如果你和eager有其他关系:

Notifications::withUser()->with('relation1')->get()

因此,如何组织和修改代码以满足您的需要取决于您

更新:

如果我还记得的话,$with总是依赖于模型列,所以如果你不选择subscription_idphoto_file_id,关系不会自动加载!
你愿意给予一个机会吗

Notifications::with('fromuser:id,name,email')->get()

相关问题