【问题标题】:Laravel models to return null relation?Laravel 模型返回空关系?
【发布时间】:2015-04-18 16:03:50
【问题描述】:

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

帖子模型:

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()

【问题讨论】:

  • 当用户未连接时是指用户未登录吗?
  • 没错,意思是当 Auth::user()->id 没有设置时

标签: php laravel eloquent


【解决方案1】:

由于您可能总是想获取关系(除非没有用户登录),我建议您在模型中执行以下操作:
(我还将关系重命名为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);
}

【讨论】:

  • 我阅读了文档,我不明白我在哪里写 trait?我该如何使用它?你能写一个例子吗? :(
  • 你不需要特质。这只是为了使范围更可重用。有关示例,请参阅我的更新答案。
  • 遇到了麻烦,解决了这个问题: public function getLikedAttribute(){ if(Auth::guest()) return false; return (bool)count($this->relations['liked']); } 可以吗?
  • 您不应该将关系和属性访问器命名为相同。这就是我使用 isLiked 和 like 的原因
  • gotcha :) 它就像一个魅力,我明白了一切,非常感谢!
猜你喜欢
  • 2016-06-21
  • 2014-10-15
  • 2013-07-04
  • 2017-11-23
  • 2020-11-06
  • 2016-02-29
  • 1970-01-01
  • 2014-11-23
  • 1970-01-01
相关资源
最近更新 更多