为什么 Laravel 5 会自动更新我的日期字段?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/35767397/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 13:20:14  来源:igfitidea点击:

Why does Laravel 5 auto update my date field?

laraveltimestamplaravel-5.2

提问by Davuz

I want to update a field (status) on the model. I would retrieve from DB and assign a new value to statuscolumn. But after the model saved, I saw another date field (published_at) also changed to same as updated_at. The action run when user click on a link as http://localhost/dashboard/gallery/publish/1.

我想更新status模型上的字段 ( )。我会从数据库中检索并为status列分配一个新值。但是在模型保存后,我看到另一个日期字段 ( published_at) 也更改为与updated_at. 当用户单击http://localhost/dashboard/gallery/publish/1链接时,操作会运行。

I don't know why the published_atupdated auto and same as updated_at?

我不知道为什么published_at更新的 auto 和updated_at?

Here is Controller code:

这是控制器代码

<?php 
class GalleryController extends Controller
{
    /**
     * Approve to publish the gallery on the web.
     *
     * @param  int  $id
     * @return Response
     */
    public function getPublish($id)
    {
        $gallery = Gallery::whereId($id)->firstOrFail();       
        $gallery->status = Gallery::STT_PUBLISH;
        $gallery->save();
        return redirect( route('backend::gallery.edit',[$gallery->id]) )->with('status', 'Done');
    }
}
?>

and Gallery Model:

画廊模型

<?php
namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

class Gallery extends Model
{
  use SoftDeletes;
  protected $table = 'gallery';
  protected $fillable = ['title', 'slug', 'content', 'category_id', 'type'];
  protected $guarded = ['published_at','creator_id','thumbnail'];
  protected $dates = ['deleted_at', 'published_at'];
}
?>

and Migration func:

迁移功能

public function up()
    {
        Schema::create('gallery', function (Blueprint $table) {
            $table->increments('id')->unsigned();
            $table->string('slug')->unique();   
            $table->tinyInteger('type')->unsigned();
            $table->integer('category_id')->unsigned()->default(0); 
            $table->string('thumbnail');   
            $table->string('title');   
            $table->text('content');
            $table->integer('status')->unsigned()->default(0);
            $table->timestamp('published_at');
            $table->integer('creator_id')->unsigned();
            $table->timestamps();            
            $table->index(['slug']);
            $table->softDeletes();
        });
        Schema::table('gallery', function (Blueprint $table) {
            $table->foreign('category_id')->references('id')->on('category');
            $table->foreign('creator_id')->references('id')->on('users');
        });
    }

UPDATE

更新

I see this config in Migration function makes problem, here: $table->timestamp('published_at');

我在迁移功能中看到这个配置有问题,在这里: $table->timestamp('published_at');

And this statement creates SQL like that:

这条语句创建了这样的 SQL:

CREATE TABLE `gallery` ( 
    ...
     `published_at` Timestamp NOT NULL ON UPDATE CURRENT_TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    ...
)

So, how to set up a timestamp field, which is not auto update on current time?

那么,如何设置一个时间戳字段,它不是当前时间自动更新的?

UPDATE 2

更新 2

Done, I modify the migration, just use dateTimeinstead of timestamp.

完成,我修改了迁移,只需使用dateTime而不是timestamp.

Use it, $table->dateTime('published_at');, this statement will not auto update on CURRENT_TIMESTAMP.

使用它,$table->dateTime('published_at');此语句不会在 CURRENT_TIMESTAMP 上自动更新。

采纳答案by Joseph

It looks like what is happening is that MySQL (or whichever database you are using) is updating the date, not Laravel.

看起来正在发生的事情是 MySQL(或您使用的任何数据库)正在更新日期,而不是 Laravel。

You need to change:

你需要改变:

$table->timestamp('published_at');

to:

到:

$table->dateTime('published_at');

Then do a php artisan migrate:refreshto rollback and recreate your tables.

然后执行php artisan migrate:refresh回滚并重新创建表。

回答by Tobias Schulz

This Post is old but for anyone who got this problem here is the simplest solution. In your migration the timestamp field just has to be nullable. Than there will no auto update trigger on this field.

这篇文章很旧,但对于在这里遇到此问题的任何人来说,这是最简单的解决方案。在您的迁移中,时间戳字段必须可以为空。这个字段不会有自动更新触发器。

$table->timestamp('published_at')->nullable();

No need for using $table->dateTime()instead of $table->timestamp().

不需要使用$table->dateTime()代替$table->timestamp()

回答by ICT Diensten 072

There is no need to change migration to

无需将迁移更改为

$table->dateTime('published_at');

Just make it

做吧

$table->timestamp('published_at')->nullable();

To display the date, you can use something like this in your model

要显示日期,您可以在模型中使用类似的内容

    public function getShortDateTimeFromTimestamp($value)
    {
        if(isset($value))
        {
            $date = date_create();

            date_timestamp_set($date, $value);

            return date_format($date, 'd-m-Y H:i');
        }
        return false;
    }

In the view

在视图中

        Published {{ $post->getShortDateTimeFromTimestamp($post->published_at) }}

To use current timestamp when storing/updating the resource, you can use

要在存储/更新资源时使用当前时间戳,您可以使用

published_at = \Carbon\Carbon::now();

回答by cytsunny

This is not a problem of Laravel, but a "feature" of MySQL.

这不是 Laravel 的问题,而是 MySQL 的一个“特性”。

According to the reference manual MySQL 5.6

根据参考手册 MySQL 5.6

TIMESTAMP and DATETIME columns have no automatic properties unless they are specified explicitly, with this exception: If the explicit_defaults_for_timestamp system variable is disabled, the first TIMESTAMP column has both DEFAULT CURRENT_TIMESTAMP and ON UPDATE CURRENT_TIMESTAMP if neither is specified explicitly.

除非明确指定,否则 TIMESTAMP 和 DATETIME 列没有自动属性,但此例外:如果已禁用explicit_defaults_for_timestamp 系统变量,则第一个 TIMESTAMP 列同时具有 DEFAULT CURRENT_TIMESTAMP 和 ON UPDATE CURRENT_TIMESTAMP(如果两者均未明确指定)。

The official site removed reference manual for older version, but when I google for the problem, from the sources that also mention about the problem, it seems that the feature was there for older version of MySQL too.

官方网站删除了旧版本的参考手册,但是当我用谷歌搜索问题时,从也提到该问题的来源中,似乎该功能也适用于旧版本的 MySQL。

Therefore, instead of changing $table->timestamp('published_at');to $table->dateTime('published_at');, you may also try to solve the problem by

因此,您也可以尝试通过以下方式解决问题,而不是更改$table->timestamp('published_at');$table->dateTime('published_at');

  1. giving a default value to the timestamp. e.g. $table->timestamp('published_at')->default(DB::raw('CURRENT_TIMESTAMP'));or $table->timestamp('published_at')->nullable()(where the default value is null)
  2. moving the line later then $table->timestamps();so that pulibhsed_atis not the firs timestamp. The default created_atand updated_atis nullable (i.e. having default value null) an will not trigger the "feature"
  1. 为时间戳提供默认值。例如$table->timestamp('published_at')->default(DB::raw('CURRENT_TIMESTAMP'));$table->timestamp('published_at')->nullable()(其中默认值为空)
  2. 稍后移动该行,$table->timestamps();以便这pulibhsed_at不是第一个时间戳。默认created_at并且可以updated_at为空(即默认值为空)并且不会触发“功能”

回答by Gabriel Ferreira Rosalino

Alternative solution is to create a migration that run this query to remove the ON UPDATE trigger of the column:

替代解决方案是创建运行此查询的迁移以删除列的 ON UPDATE 触发器:

ALTER TABLE queued_posts CHANGE scheduled_publish_time scheduled_publish_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP

ALTER TABLE queued_posts CHANGE scheduled_publish_time scheduled_publish_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP