Laravel 在更新时更改 created_at
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/34673729/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Laravel changes created_at on update
提问by Skatch
I found this answeron the subject, but it doesn't work for me.
So, I make an entry in the database:
所以,我在数据库中创建一个条目:
// Write lead to database
$lead = Lead::create($lead_data);
And the timestamps look like this, which is good:
时间戳看起来像这样,这很好:
| 2016-01-08 10:34:15 | 2016-01-08 10:34:15 |
But then I make a request to an external server, and I need to update the row:
但随后我向外部服务器发出请求,我需要更新该行:
$lead->user_id = $response['user_id'];
$lead->broker_id = $response['broker_id'];
$lead->save();
and the created_at field gets changed:
并且 created_at 字段被更改:
| 2016-01-08 04:34:17 | 2016-01-08 10:34:17 |
How do I solve this problem?
我该如何解决这个问题?
EDIT
编辑
I need a solution that would just modify the behavior without dropping columns or resetting migrations. The fix has to be performed on a live database without touching the data. As suggested below, I tried the following migration:
我需要一个只修改行为而不删除列或重置迁移的解决方案。必须在不接触数据的情况下在实时数据库上执行修复。如下所示,我尝试了以下迁移:
$table->datetime('created_at')->default(DB::raw('CURRENT_TIMESTAMP'))->change();
but nothing happens. The created_at field still gets modified on update.
但什么也没有发生。created_at 字段仍然在更新时被修改。
回答by patricus
If you're on Laravel 5.2 and using MySQL, there was a bit of a "bug" introduced with the timestamps. You can read all about the issue on github here. It has to do with the timestamp defaults, and MySQL automatically assigning DEFAULT CURRENT_TIMESTAMP or ON UPDATE CURRENT_TIMESTAMP attributes under certain conditions.
如果您使用的是 Laravel 5.2 并使用 MySQL,那么时间戳会引入一些“错误”。您可以在此处阅读 github 上有关该问题的所有信息。它与时间戳默认值有关,MySQL 在某些条件下自动分配 DEFAULT CURRENT_TIMESTAMP 或 ON UPDATE CURRENT_TIMESTAMP 属性。
Basically, you have three options.
基本上,您有三个选择。
- Update MySQL variable:
- 更新 MySQL 变量:
If you set the explicit_defaults_for_timestamp
variable to TRUE
, no timestamp column will be assigned the DEFAULT CURRENT_TIMESTAMP or ON UPDATE CURRENT_TIMESTAMP attributes automatically. You can read more about the variable here.
如果将该explicit_defaults_for_timestamp
变量设置为TRUE
,则不会自动为时间戳列分配 DEFAULT CURRENT_TIMESTAMP 或 ON UPDATE CURRENT_TIMESTAMP 属性。您可以在此处阅读有关该变量的更多信息。
- Use nullable timestamps:
- 使用可为空的时间戳:
Change $table->timestamps()
to $table->nullableTimestamps()
. By default, the $table->timestamps()
command creates timestamp fields that are not nullable. By using $table->nullableTimestamps()
, your timestamp fields will be nullable, and MySQL will not automatically assign the first one the DEFAULT CURRENT_TIMESTAMP or ON UPDATE CURRENT_TIMESTAMP attributes.
更改$table->timestamps()
为$table->nullableTimestamps()
。默认情况下,该$table->timestamps()
命令创建不可为空的时间戳字段。通过使用$table->nullableTimestamps()
,您的时间戳字段将可以为空,并且 MySQL 不会自动为第一个字段分配 DEFAULT CURRENT_TIMESTAMP 或 ON UPDATE CURRENT_TIMESTAMP 属性。
- Define the timestamps yourself:
- 自己定义时间戳:
Instead of using $table->timestamps
, use $table->timestamp('updated_at'); $table->timestamp('created_at');
yourself. Make sure your 'updated_at' field is the first timestamp in the table, so that it will be the one that is automatically assign the DEFAULT CURRENT_TIMESTAMP or ON UPDATE CURRENT_TIMESTAMP attributes.
与其使用$table->timestamps
,$table->timestamp('updated_at'); $table->timestamp('created_at');
不如使用自己。确保您的“updated_at”字段是表中的第一个时间戳,以便它自动分配 DEFAULT CURRENT_TIMESTAMP 或 ON UPDATE CURRENT_TIMESTAMP 属性。
回答by sgrover
Skatch - I think your solution above is not quite right, but is probaby fine in this case.
Skatch - 我认为你上面的解决方案不太正确,但在这种情况下可能很好。
The issue is that you are getting the PHP date, not the default MYSQL timestamp for your default. When you run that migration you end up with a statement like this:
问题是您获取的是 PHP 日期,而不是默认的默认 MYSQL 时间戳。当您运行该迁移时,您最终会得到如下语句:
alter table alter column created_at default '2016:02:01 12:00:00';
Notice the string for your date. When you run your migration THAT date will always be used for your created_at, not the current date when a record is added days later.
注意日期的字符串。当您运行迁移时,该日期将始终用于您的 created_at,而不是几天后添加记录时的当前日期。
Instead of doing "date('Y:m:d H:i:s')", you can do DB::raw('current_timestamp') to address this issue.
您可以执行 DB::raw('current_timestamp') 来解决此问题,而不是执行 "date('Y:m:d H:i:s')"。
(sry, couldn't just add a comment above - my reputation is not high enough yet...)
(对不起,不能只是在上面添加评论 - 我的声誉还不够高......)
回答by sgrover
Posting this as a top level answer, summarizing our comment discussion.
将此作为顶级答案发布,总结我们的评论讨论。
First, there is a date bugintroduced in Laravel - as noted by @patricus. The suggested solutions in the bug discussion are to either use nullableTimestamps() instead of just timestamps(), or to create the created_at and updated_at fields directly - $table->timestamp('updated_at')->change()
.
首先,Laravel 中引入了一个日期错误- 正如@patricus 所指出的。错误讨论中建议的解决方案是使用 nullableTimestamps() 而不仅仅是 timestamps(),或者直接创建 created_at 和 updated_at 字段 - $table->timestamp('updated_at')->change()
。
This can also be fixed with raw SQL. An ALTER statement similar to this
这也可以通过原始 SQL 修复。与此类似的 ALTER 语句
alter table loader_rawvalues MODIFY column updated_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
That can be applied directly to your existing DB tables (Test it first, or course!). OR you can use DB::unprepared() to apply it from your migration - for example:
这可以直接应用于您现有的数据库表(首先测试它,或者当然!)。或者您可以使用 DB::unprepared() 从您的迁移中应用它 - 例如:
class CreateMyTable extends Migration
{
public function up()
{
Schema::create('mytable', function (Blueprint $table) {
$table->bigIncrements('id');
// ...
$table->timestamps();
});
DB::unprepared('alter table mytable MODIFY column updated_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP');
}
}
回答by Khairul Imam
That must be an issue on your table field definition. I faced the same issue recently, and when I check my table, the created_at
has an "EXTRA
" with value on update CURRENT_TIMESTAMP
, to have Laravel behave normally just update the field definition with something like:
这一定是您的表字段定义的问题。我最近遇到了同样的问题,当我检查我的表时,created_at
有一个 " EXTRA
" 值on update CURRENT_TIMESTAMP
,要让 Laravel 正常运行,只需使用以下内容更新字段定义:
ALTER TABLE table_name CHANGE created_at created_at timestamp NOT NULL default CURRENT_TIMESTAMP;