Php 如何在雄辩的模型中创建complexe虚拟列?
这个问题与我的问题有关,但我把我真正的问题简化得太多了。因此,我创建了一个单独的问题: 我有两张桌子。一个以天为单位保存与名称相关的间隔,如Php 如何在雄辩的模型中创建complexe虚拟列?,php,mysql,laravel,eloquent,Php,Mysql,Laravel,Eloquent,这个问题与我的问题有关,但我把我真正的问题简化得太多了。因此,我创建了一个单独的问题: 我有两张桌子。一个以天为单位保存与名称相关的间隔,如双月=15,另一个列出与间隔相关的周期性动作 我想列出下一个在纯SQL中很简单的周期性操作: SELECT *, DATE_ADD(updated_at, INTERVAL days DAY) AS next_action FROM periodic_actions INNER JOIN intervals ON interval_id = interv
双月=15
,另一个列出与间隔相关的周期性动作
我想列出下一个在纯SQL中很简单的周期性操作:
SELECT *, DATE_ADD(updated_at, INTERVAL days DAY) AS next_action
FROM periodic_actions
INNER JOIN intervals ON interval_id = intervals.id
HAVING next_action > NOW()
这是我的桌子:
CREATE TABLE `intervals` (
`id` INT NOT NULL AUTO_INCREMENT,
`name` VARCHAR(45) NULL,
`days` INT NULL,
PRIMARY KEY (`id`));
CREATE TABLE `periodic_actions` (
`id` INT NOT NULL AUTO_INCREMENT,
`interval_id` INT NOT NULL,
`name` VARCHAR(45) NULL,
`updated_at` TIMESTAMP NOT NULL,
PRIMARY KEY (`id`));
以及间隔的内容:
+----+----------+------+
| id | name | days |
+----+----------+------+
| 1 | daily | 1 |
| 2 | monthly | 30 |
| 3 | annually | 365 |
+----+----------+------+
我想在我的虚拟专栏next\u action
上使用Elounting where构建相同的查询:
Action::orderBy('next_action', 'asc')
->where('next_action', '>', Carbon::now())
->get()
我拥有的最接近的,我无法隐藏在我的模型中的是:
Action::join('intervals', 'interval_id', '=', 'intervals.id')
->select(['*', DB::RAW('DATE_ADD(updated_at, INTERVAL days DAY) AS next_action')])
->havingRaw(DB::RAW('next_action > NOW()'))->get();
当然,我有这个基本模型:
class Action extends Model
{
protected $table = 'periodic_actions';
public function interval()
{
return $this->belongsTo(Interval::class);
}
}
解决方案1:使用全局范围将字段添加到select语句中 虚拟列的一个问题是,如果您不阻止,我们将尝试更新它们。您可以将其从$fillable数组中排除,并在模型中使用添加虚拟列,如:
protected static function boot()
{
parent::boot();
static::addGlobalScope('next_action', function (Builder $builder) {
$builder->addSelect(DB::raw('DATE_ADD(updated_at, INTERVAL days DAY) AS next_action'));
});
}
您必须记住,这将使您的模型与MySQL耦合,因为您使用的日期函数在像sqlite这样的数据库中不起作用
解决方案2:使用MySQL视图
通常,当我有多个计算字段时,我会创建一个MySQL视图。创建包含所有所需计算字段的视图,然后可以为该视图创建新的雄辩模型,而不必担心查询范围
需要注意的一点是,您当然不能在此模型上使用create/update/delete,但如果您仅将模型用于显示目的,这应该不会有问题。如果涉及两个表,则创建视图模型可能是更好的解决方案。检查:您是否将此方法放在模型本身上?是的,这是模型类中的静态方法。OP希望在其查询中使用
where()
。但这个解决方案仍然无法实现这一点,对吗?OP需要使用having()
?我同意哪里更好,因为我可以从剑道网格构建通用过滤器。但是boot
解决方案并非如此bad@Mozammil,您是对的,您必须将have与计算字段一起使用。