Laravel 模型到 return 空关系?

Laravel models to return null relation?

我正在为照片 post 写一个网站,我有这些与喜欢相关的功能(它们确定用户是否喜欢特定的 post)

Post 型号:

public function likes()
{
    return $this->hasMany('Like');
}

public function isLiked()
{
    return $this->likes()->where('user_id', Auth::user()->id);
}

Post控制器函数举例:

public function postsByType($type)
{
    if($this->user){
        $posts = Post::with('isLiked')->where('type', '=', $type)->paginate(12);
    } else {
        $posts = Post::where('type', '=', $type)->paginate(12);
    }
    return $posts;
}

当用户未登录时,有什么方法可以在 MODEL 函数中 return null没有 运行 查询?

我想避免在 post 控制器中写 if

我考虑过以下解决方案,但它不起作用...

public function isFollowing()
{
    return $this->setRelation('isFollowing', null);

}

出现此错误: Call to undefined method Illuminate\Database\Query \Builder::addEagerConstraints()

因为你可能总是想获取关系(除非没有用户登录)我建议你在你的模型中做这样的事情:
(我还将关系重命名为 liked,稍后您会看到原因)

public function newQuery(){
    $query = parent::newQuery();
    if(Auth::check()){
        $query->with('liked');
    }
    return $query;
}

现在每次查询 运行 如果用户已登录,模型 with('isLiked') 将被添加。

不过还有一个问题。如果您访问 isLiked,查询仍然是 运行。甚至每个 post 因为它不是急于加载的。您可以通过添加属性访问器来解决此问题:

public function getIsLikedAttribute(){
    if(Auth::guest) return false;
    return ! $this->liked->isEmpty();
}

所以在你看来你可以这样做:

@if($post->isLiked)

注意:将newQuery()里面的东西移到全局范围内会更好。如果您有兴趣,请务必查看 the documentation 中的操作方法。

这是一个范围示例。创建一个 class,我们称它为 LikedScope:

class LikedScope implements Illuminate\Database\Eloquent\ScopeInterface {
    public function apply(Builder $builder, Model $model){
        if(Auth::check()){
            $builder->with('liked');
        }
    }

    public function remove(Builder $builder, Model $model){

    }
}

然后将其添加到您的模型中:

public static function boot(){
    parent::boot();
    static::addGlobalScope(new LikedScope);
}