Laravel另一种附加模型

时间:2017-01-17 13:56:22

标签: php laravel

我正在建造一个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();

1 个答案:

答案 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);
}

希望这适合你。