【问题标题】:Convert local scope to global scope or query by parent attribute将本地范围转换为全局范围或按父属性查询
【发布时间】:2020-05-28 04:31:38
【问题描述】:

我想检索属于活动帖子的所有 cmets。

我的Posts 模型上有一个本地范围,看起来像这样。

public function scopePublic($query) {
    return $query->whereHas('post', function ($q) {
        $q->where('is_public', true);
    });
}

效果很好,但只要我想将其转换为这样的全局范围,就会与 PHP message: PHP Fatal error: Allowed memory size of X bytes exhausted 中断:

static::addGlobalScope('is_public', function (Builder $builder) {
    return $builder->whereHas('post', function ($q) {
        $q->where('is_public', true);
    });
});

我的最终目标是让所有评论查询仅显示公共 cmets,除非我明确要求不要这样做。

我已经通过了很多解决方案。我已尝试加入 cmets 上的帖子,并尝试添加子选择以失败。

$builder->addSelect(['is_public' => Post::select('is_private')
   ->whereColumn('id', 'comment.post_id')->limit(1)
]);

$builder->join('posts','posts.id','=','comments.post_id')
    ->where('comments.is_private', false);

【问题讨论】:

    标签: sql laravel eloquent


    【解决方案1】:

    创建一个新类 PublicScope

    use Illuminate\Database\Eloquent\Scope;
    
    class CommentPublicScope implements Scope
    {
        /**
         * Apply the scope to a given Eloquent query builder.
         *
         * @param  \Illuminate\Database\Eloquent\Builder  $builder
         * @param  \Illuminate\Database\Eloquent\Model  $model
         * @return void
         */
        public function apply(Builder $builder, Model $model)
        {
            $builder->whereHas('post', function ($q) {
                $q->where('is_public', true);
            });
        }
    }
    

    然后就可以添加全局作用域了

    Class Comment extends Model
    {
        protected static function boot()
        {
            parent::boot();
            static::addGlobalScope(new CommentPublicScope);
        }
    }
    

    【讨论】:

    • 这样做会引发PHP message: PHP Fatal error: Allowed memory size of X bytes exhausted
    • 好吧,如果您调用数据库中所有的 cmets,并且如果您有数千或数百万个,那就不足为奇了。有或没有范围。在所有情况下,它都与您的问题无关。
    • 这不是因为我耗尽了我的记忆——这是因为这个代码示例的递归错误。我的测试数据库中只有 10 个 cmets,我将查询限制为 3 个。
    • 你在哪里添加了全局作用域?
    • @NicklasKevinFrank 更精确地说明了您需要在哪里声明全局范围
    猜你喜欢
    • 2021-03-05
    • 2014-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-15
    • 2013-11-06
    • 1970-01-01
    • 2015-09-30
    相关资源
    最近更新 更多