我正在建造一个api Laravel。在我的消息模型中,我附加了以下内容:
/**
* @var array
*/
protected $appends = ['subscribed'];
/**
* @return mixed
*/
public function getSubscribedAttribute()
{
return $this->isSubscribedBy();
}
IsSubscribedBy();
生活在一个如下所示的特征中:
/**
* @return mixed
*/
public function isSubscribedBy()
{
return $this->subscriptions()
->where('user_id', Auth::user()->id)
->exists();
}
这是有效的,但这样做有n + 1
问题,我无法在algolia中加载php artisan scout:import "App\Messages\Message"
的消息显然会引发错误(因为没有人登录但是它正在寻找某人:Auth::user()->id):
[ErrorException]
试图获得非对象的属性
那么有更好的方法吗?我已经尝试过分形,但后来仍然遇到n + 1
问题。
--- --- EDIT
我这样回来了:
/**
* @return mixed
*/
public function index()
{
return Message::orderBy('created_at', 'DESC')
->paginate(10);
}
因此,对于每条消息,它将执行此查询:
$this->subscriptions()
->where('user_id', Auth::user()->id)
->exists();
答案 0 :(得分:1)
如果用户根本没有登录,那么很明显他们无法订阅。所以你可以这样做:
public function isSubscribedBy()
{
if(!Auth::check()) {
return false;
}
return $this->subscriptions()
->where('user_id', Auth::user()->id)
->exists();
}
或者,如果您需要false
以外的其他内容,请null
返回。
好了解如何急切加载它,首先你需要将你急切的加载限制在当前用户:
return Message::orderBy('created_at', 'DESC')->with(['subscriptions'=> function ($query) {
$query->where('user_id', '=', Auth::user()->id);
}])->paginate(10);
然后,它只会加载当前用户对邮件的订阅。现在在你的属性getter中,你需要访问已经急切加载而不是雄辩的getter的集合。您只需删除()
上的subscriptions()
并使用集合方法而不是雄辩的方法(大多数时候看起来完全相同)即可。所以你的功能看起来像这样:
public function isSubscribedBy()
{
return ($this->subscriptions->count() > 0);
}
希望这适合你。