Laravel 迁移默认值
Posted
技术标签:
【中文标题】Laravel 迁移默认值【英文标题】:Laravel migration default value 【发布时间】:2016-10-06 09:17:58 【问题描述】:我不明白迁移中default
选项的作用是什么。
我可以看到数据库中的列是用默认值定义的,但是模型完全忽略了它。假设我有一个 Book
模型,它反映了数据库中的 books
表。我有迁移来创建 books 表:
Schema::create('books', function (Blueprint $table)
$table->increments('id');
->string('author');
->string('title');
->decimal('price', 4, 1)->default(100);
->timestamps();
);
当我创建 Book
模型的新实例时,我看到:
$book = new Book();
var_dump($book->price); //Always 0...
默认值被忽略,属性设置不正确。 好的,我可以得到它,因为它是一个新对象,它不应该从数据库中获取默认值。 但是如果我尝试保存模型,例如:
$book = new Book();
$book->author = 'Test'
$book->title = 'Test'
$book->save();
它是在数据库中的price
字段中保存0!
那么迁移中default
选项的意义何在?
顺便说一句... 如果模型在迁移中看到(如果存在)字段类型和行为是什么而不是在模型和迁移中手动定义它,那不是更好吗?此外,甚至可以为模型自动创建验证器。我认为迁移结构的微小变化是可能的,那为什么不是这样呢?
【问题讨论】:
在 Laravel 文档中,它说“在修改列之前,请务必将教义/dbal 依赖项添加到 composer.json 文件。Doctrine DBAL 库用于确定列的当前状态并创建对列进行指定调整所需的 SQL 查询。”你有这种依赖吗? 我没有修改任何列,我为什么要这样? 因为default($value)
是迁移中的修饰符,这是修饰符的先决条件。
【参考方案1】:
将默认值放在单引号中,它将按预期工作。迁移示例:
$table->increments('id');
$table->string('name');
$table->string('url');
$table->string('country');
$table->tinyInteger('status')->default('1');
$table->timestamps();
编辑: 在你的情况下 ->default('100.0');
【讨论】:
它没有用。添加单引号并运行php artisan migrate:refresh
后仍然忽略默认值
我在发布答案之前对其进行了测试,您确定它不起作用吗?然后我会删除这个答案
用整数值试试?我知道您想要默认浮动,但请尝试一下
现在有了你的$table->tinyInteger('status')->default('1');
,它就可以工作了。可能是因为我用来保存模型的Form::model
。在那种情况下,我必须手动定义模型中的默认值吗?
它对我有用。但是有人知道这是否是预期的行为吗?看起来很奇怪。【参考方案2】:
您可以使用 default() 简单地设置默认值。看例子
$table->enum('is_approved', array('0','1'))->default('0');
我这里使用了枚举,默认值为0。
【讨论】:
【参考方案3】:在 Laravel 6 中,您必须将“更改”添加到迁移文件中,如下所示:
$table->enum('is_approved', array('0','1'))->default('0')->change();
【讨论】:
【参考方案4】:参加聚会可能有点太晚了,但希望这对有类似问题的人有所帮助。
您的默认值不起作用的原因是迁移文件在您的数据库(mysql 或 PostgreSQL 等)中设置了默认值,而不是在您的 Laravel 应用程序中。
让我用一个例子来说明。
这行意味着 Laravel 正在生成一个新的 Book 实例,正如你的模型中指定的那样。新的Book
对象将根据与模型关联的表具有属性。到目前为止,数据库上没有写入任何内容。
$book = new Book();
现在以下几行设置Book
对象的每个属性的值。还是一样,数据库上还没有写任何东西。
$book->author = 'Test'
$book->title = 'Test'
这一行是写入数据库的行。将对象传递到数据库后,空字段将由数据库填充(可能是默认值,可能是 null,或者您在迁移文件中指定的任何值)。
$book->save();
因此,默认值在保存到数据库之前不会弹出。
但是,这还不够。如果您尝试访问$book->price
,它仍然为空(或0,我不确定)。保存只是将默认值添加到数据库中的记录中,不会影响您随身携带的Object。
因此,要获取具有填充默认值的实例,您必须重新获取该实例。您可以使用
Book::find($book->id);
或者,通过刷新实例更复杂的方式
$book->refresh();
然后,下次您尝试访问该对象时,它将使用默认值填充。
【讨论】:
【参考方案5】:您面临的问题与迁移文件无关。该值每次都变为 0,因为您没有更改模型上的 $fillable 。当您忘记将最近添加的列添加到其模型的 $fillable 时,Laravel 会插入 0。
【讨论】:
以上是关于Laravel 迁移默认值的主要内容,如果未能解决你的问题,请参考以下文章