首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在雄辩的模型中创建复杂的虚拟列?

如何在雄辩的模型中创建复杂的虚拟列?
EN

Stack Overflow用户
提问于 2019-02-06 14:36:55
回答 1查看 3.1K关注 0票数 1

这个问题与这一个有关,但我过于简化了我的实际问题。因此,我提出了一个分开的问题:

我有两张桌子。一个保持间隔,以天为单位,与名称相关联,如bimonthly = 15和其他列出的周期性动作,并与间隔相关联。

我想列出在纯SQL中很容易实现的下一个定期操作:

代码语言:javascript
复制
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()

这是我的桌子:

代码语言:javascript
复制
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`));

以及间隔期的内容:

代码语言:javascript
复制
+----+----------+------+
| id | name     | days |
+----+----------+------+
|  1 | daily    |    1 |
|  2 | monthly  |   30 |
|  3 | annually |  365 |
+----+----------+------+

我想以雄辩的方式构建同样的查询,在虚拟列next_action上使用next_action

代码语言:javascript
复制
Action::orderBy('next_action', 'asc')
    ->where('next_action', '>', Carbon::now())
    ->get()

我拥有的最接近的,我无法隐藏在我的模型是:

代码语言:javascript
复制
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();

当然,我有一个基本模型:

代码语言:javascript
复制
class Action extends Model
{
    protected $table = 'periodic_actions';

    public function interval() 
    {
        return $this->belongsTo(Interval::class);
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-02-06 14:56:03

解决方案1:使用全局范围将字段添加到select语句

虚拟列的一个问题是,如果您不阻止它,就会尝试更新它们。您可以从$fillable数组中排除它,并在模型中使用全球范围添加虚拟列,如下所示:

代码语言:javascript
复制
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,但是如果您只是为了显示目的而使用该模型,那就没有问题了。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54556064

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档