我有一个具有SoftDelete功能的Post Model和一个活动布尔字段,用于确定Post活动状态。
class Post extends Model implements SluggableInterface
{
use SoftDeletes;
protected $primaryKey = 'post_id';
.
.
.
}
此外,Post Model还有一个start_date
字段,用于保存发布Post的开始日期。
现在,除了非软删除模型之外,我想使用Anonymous GlobalScope Laravel 5.2来过滤和获取活动帖子,以及那些他们的start_dat
e为NULL或小于now()的帖子。
为此,我将其添加到Post
模型中:
protected static function boot()
{
parent::boot();
static::addGlobalScope('active', function(Builder $builder){
$builder->where('active',1);
});
static::addGlobalScope('scheduled', function(Builder $builder){
$builder
->whereNull('start_date')->orWhere(function ($query) {
$query->where('start_date', '<=', Carbon::now());
});
});
}
单独使用active
全局作用域可以正常工作,但当我添加第二个名为scheduled
的作用域时,会返回所有记录,包括softDeleted和inActive模型。
什么是问题?我听不懂
这是因为您使用的是orWhere
。在这些情况下,使用Laravel调试栏查看Raw SQL非常有用,因为我敢打赌你的select语句看起来像这样:
SELECT * FROM table WHERE deleted_at IS NULL AND active=1 AND state_date IS NULL OR (start_Date <= now())
这将选择任何符合"一或"标准的内容。
要解决这个问题,您应该将scheduled
设置为这样。
static::addGlobalScope('scheduled', function(Builder $builder) {
$builder->where(function($query)) {
$query->whereNull('start_date');
$query->orWhere('start_date', '<=', Carbon::now());
});
});
这将(希望)使您的查询看起来像这样:
SELECT * FROM table WHERE deleted_at IS NULL AND active=1 AND (state_date IS NULL OR start_Date <= now())
这就是我认为你想要的。