Laravel模型返回空关系


Laravel models to return null relation?

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

后模型:

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

后控制器功能,例如:

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函数中返回null,而不运行查询?

如果在后控制器中,我想避免写

我想过以下解决方案,但它不起作用。。。

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,那么查询无论如何都会运行。甚至对于每一个帖子,因为它并不急于加载。您可以通过添加属性访问器来修复此问题:

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

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

@if($post->isLiked)

注意:最好将newQuery()中的内容移动到全局范围。如果你感兴趣,一定要在文档中查看如何做到这一点。

下面是一个带范围的示例。创建一个类,我们称之为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);
}