Laravel迁移默认值

nro*_*fis 34 laravel laravel-5 laravel-5.2

我不明白该default选项在迁移中的作用是什么.

我可以看到数据库中的列是使用默认值定义的,但模型完全忽略它.假设我有一个Book反映books数据库中表的模型.我有迁移来创建books表:

Schema::create('bools', function (Blueprint $table) {
    $table->increments('id');
          ->string('author');
          ->string('title');
          ->decimal('price', 4, 1)->default(100);
          ->timestamps();
});
Run Code Online (Sandbox Code Playgroud)

当我创建一个新的Book模型实例时,我看到:

$book = new Book();
var_dump($book->price); //Always 0...
Run Code Online (Sandbox Code Playgroud)

将忽略默认值,并且未正确设置属性.好的,我可以得到它,因为它是一个新对象,它不应该从DB获取默认值.如果我试图保存模型,如:

$book = new Book();
$book->author = 'Test'
$book->title = 'Test'
$book->save();
Run Code Online (Sandbox Code Playgroud)

它在数据库中的字段中保存0price!

那么default迁移中的选项有什么意义呢?

顺便说一句......如果模型在迁移内部(如果存在)看到了什么是字段类型和行为而不是在模型和迁移中手动定义它,那就不是更好了?而且,甚至可以自动为模型创建验证器.我认为迁移结构的变化很小,所以为什么不那样?

Kha*_*ukh 71

将默认值放在单引号中,它将按预期工作.迁移的一个例子:

$table->increments('id');
            $table->string('name');
            $table->string('url');
            $table->string('country');
            $table->tinyInteger('status')->default('1');
            $table->timestamps();
Run Code Online (Sandbox Code Playgroud)

编辑:在你的情况下 - >默认('100.0');

  • 它没有用。添加单引号并运行 `php artisan migrate:refresh` 后,它仍然忽略默认值 (2认同)
  • 它对我有用。但是有人知道这是否是有意的行为吗?看起来很奇怪。 (2认同)

小智 8

参加聚会可能有点太晚了,但希望这可以帮助有类似问题的人。

默认值不起作用的原因是迁移文件在您的数据库(MySQL 或 PostgreSQL 或其他)中设置默认值,而不是在 Laravel 应用程序中。

让我用一个例子来说明。

此行表示 Laravel 正在生成一个新的 Book 实例,如模型中指定的那样。新Book对象将具有根据与模型关联的表的属性。到目前为止,数据库中还没有写入任何内容。

$book = new Book();
Run Code Online (Sandbox Code Playgroud)

现在,以下几行正在设置对象的每个属性的值Book。还是一样,数据库中还没有写入任何内容。

$book->author = 'Test'
$book->title = 'Test'
Run Code Online (Sandbox Code Playgroud)

这一行是写入数据库的行。将对象传递到数据库后,空字段将由数据库填充(可能是默认值,可能为空,或者您在迁移文件中指定的任何内容)。

$book->save();
Run Code Online (Sandbox Code Playgroud)

因此,在将其保存到数据库之前,默认值不会弹出。

但是,这还不够。如果您尝试访问$book->price,它仍然为 null (或 0,我不确定)。保存只是将默认值添加到数据库中的记录中,不会影响您携带的对象。

因此,要获取具有填充默认值的实例,您必须重新获取该实例。您可以使用

Book::find($book->id);
Run Code Online (Sandbox Code Playgroud)

或者,通过刷新实例来更复杂的方式

$book->refresh();
Run Code Online (Sandbox Code Playgroud)

然后,下次尝试访问该对象时,它将填充默认值。


小智 5

您可以使用 default() 简单地设置默认值。参见示例

 $table->enum('is_approved', array('0','1'))->default('0');
Run Code Online (Sandbox Code Playgroud)

我这里使用了enum,默认值是0。


小智 5

在 Laravel 6 中,您必须将“更改”添加到迁移文件中,如下所示:

$table->enum('is_approved', array('0','1'))->default('0')->change();
Run Code Online (Sandbox Code Playgroud)