Laravel模型返回null关系?

时间:2015-02-17 20:15:27

标签: php laravel eloquent

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

发布模型:

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 没有运行查询

我想避免在帖子控制器中写 if

我考虑过以下解决方案,但它没有工作......

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

}

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

1 个答案:

答案 0 :(得分:3)

由于您可能总是想要获取关系(除非没有用户登录),我建议您在模型中执行以下操作:
(我还将关系重命名为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()内的内容移动到全局范围会更好。如果您有兴趣,请务必查看如何在the documentation中执行此操作。

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