Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/282.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 如何在雄辩的模型中创建complexe虚拟列?_Php_Mysql_Laravel_Eloquent - Fatal编程技术网

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与计算字段一起使用。