如何使用架构生成器添加虚拟列?

时间:2015-01-02 23:19:18

标签: laravel mariadb

我正在创建一个这样的表,

Schema::create('booking_segments', function (Blueprint $table) {
    $table->increments('id');

    $table->datetime('start')->index();
    $table->integer('duration')->unsigned();
    $table->string('comments');
    $table->integer('booking_id')->unsigned();
    $table->foreign('booking_id')->references('id')->on('bookings')->onDelete('cascade');
});

但我想添加一个额外的列。在原始SQL中看起来像这样:

ALTER TABLE booking_segments ADD COLUMN `end` DATETIME AS (DATE_ADD(`start`, INTERVAL duration MINUTE)) PERSISTENT AFTER `start`

如何在迁移中添加它?我还需要在其上创建一个索引。

3 个答案:

答案 0 :(得分:13)

我知道这是一个老问题,但是有一种方法可以使用自Laravel 5.3以来的模式构建器,所以我想我会把它放在这里以便完整。

您可以使用laravel 5.3 column modifiers virtualAs或storedAs。

因此,要创建要在每个查询中计算的虚拟生成列,您将创建如下列的列:

$table->dateTime('created_at')->virtualAs( 'DATE_ADD(`start`, INTERVAL duration MINUTE)' );

要创建存储生成的列,您可以改为创建列:

$table->dateTime('created_at')->storedAs( 'DATE_ADD(`start`, INTERVAL duration MINUTE)' );

答案 1 :(得分:1)

我不认为你可以使用架构构建器(如果我错了,请有人纠正我)但你总是可以“退回”原始SQL:

DB::statement('ALTER TABLE booking_segments ADD COLUMN `end` DATETIME AS (DATE_ADD(`start`, INTERVAL duration MINUTE)) PERSISTENT AFTER `start`');

答案 2 :(得分:0)

你也可以使用 Laravel Events 来达到同样的结果,而无需使用 storageAs 或 virtualAs。 供参考:Laravel: performing some task on every insert/update when using Query Builder or Eloquent ORM

我是这样做的:

class MyModel extends Model
{
    /** .... **/

    /**
     * The "booted" method of the model.
     *
     * @return void
     */
    protected static function booted()
    {
        static::creating(function ($option) {
            $option->column1 = $option->column2 + 2;
        });

        static::updating(function ($option) {
            $option->column1 = $option->column2 + 2;
        });
    }
}