我想使用Laravel Schema Builder/Migrations创建一个默认值为CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP的时间戳列。我已经多次阅读Laravel文档,我不知道如何将其作为时间戳列的默认值。
timestamps()函数将它所生成的两列的默认值设置为0000-00-00 00:00。
我想使用Laravel Schema Builder/Migrations创建一个默认值为CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP的时间戳列。我已经多次阅读Laravel文档,我不知道如何将其作为时间戳列的默认值。
timestamps()函数将它所生成的两列的默认值设置为0000-00-00 00:00。
当前回答
使用保罗·弗雷塔斯的建议。
在Laravel修复此问题之前,您可以在Schema::create运行之后运行标准数据库查询。
Schema::create("users", function($table){
$table->increments('id');
$table->string('email', 255);
$table->string('given_name', 100);
$table->string('family_name', 100);
$table->timestamp('joined');
$table->enum('gender', ['male', 'female', 'unisex'])->default('unisex');
$table->string('timezone', 30)->default('UTC');
$table->text('about');
});
DB::statement("ALTER TABLE ".DB::getTablePrefix()."users CHANGE joined joined TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL");
它对我产生了奇效。
其他回答
使用保罗·弗雷塔斯的建议。
在Laravel修复此问题之前,您可以在Schema::create运行之后运行标准数据库查询。
Schema::create("users", function($table){
$table->increments('id');
$table->string('email', 255);
$table->string('given_name', 100);
$table->string('family_name', 100);
$table->timestamp('joined');
$table->enum('gender', ['male', 'female', 'unisex'])->default('unisex');
$table->string('timezone', 30)->default('UTC');
$table->text('about');
});
DB::statement("ALTER TABLE ".DB::getTablePrefix()."users CHANGE joined joined TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL");
它对我产生了奇效。
作为未来谷歌人的额外可能性
我发现,当记录被创建但从未被修改时,在updated_at列中设置null更有用。它减少了数据库大小(好吧,只是一点点),它可以在第一眼看到数据从未被修改过。
我使用的是:
$table->timestamp('created_at')->useCurrent();
$table->timestamp('updated_at')->default(DB::raw('NULL ON UPDATE CURRENT_TIMESTAMP'))->nullable();
(在Laravel 7+8与mysql 8)。
编辑:因为Laravel 8你还可以使用:
$table->timestamp('created_at')->useCurrent();
$table->timestamp('updated_at')->nullable()->useCurrentOnUpdate();
达到同样的效果。
感谢@bilogic指出这一点。
我在Laravel中使用以下自定义:
默认created_at为当前时间戳 更新记录时更新时间戳
首先,我将在Laravel的根目录下创建一个helpers.php文件,并插入以下内容:
<?php
if (!function_exists('database_driver')) {
function database_driver(): string
{
$connection = config('database.default');
return config('database.connections.' . $connection . '.driver');
}
}
if (!function_exists('is_database_driver')) {
function is_database_driver(string $driver): bool
{
return $driver === database_driver();
}
}
在作曲家。json,我将插入以下到自动加载。这允许编写器自动发现helpers.php。
"autoload": {
"files": [
"app/Services/Uploads/Processors/processor_functions.php",
"app/helpers.php"
]
},
我在Laravel模型中使用以下方法。
if (is_database_driver('sqlite')) {
$table->timestamps();
} else {
$table->timestamp('created_at')->default(\DB::raw('CURRENT_TIMESTAMP'));
$table->timestamp('updated_at')
->default(DB::raw('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'));
}
这允许我的团队继续使用sqlite进行单元测试。ON UPDATE CURRENT_TIMESTAMP是MySQL的快捷方式,在sqlite中不可用。
唯一对我有用的是
DB::statement("ALTER TABLE orders CHANGE updated_at updated_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP");
从Laravel 5.1.26开始,标签为2015-12-02,添加了useCurrent()修饰符:
Schema::table('users', function ($table) {
$table->timestamp('created')->useCurrent();
});
PR 10962(随后是commit 15c487fe)导致了这一添加。
您可能还想阅读感兴趣的第3602和11518期。
基本上,MySQL 5.7(默认配置)要求您为时间字段定义一个默认值或可空值。