为什么 Laravel 5 会自动更新我的日期字段?
Why does Laravel 5 auto update my date field?
我想更新模型上的字段 (status
)。我将从数据库中检索并为 status
列分配一个新值。但是模型保存后,我看到另一个日期字段 (published_at
) 也更改为与 updated_at
相同。
当用户点击 link 作为 http://localhost/dashboard/gallery/publish/1 时的操作 运行。
我不知道为什么 published_at
自动更新并与 updated_at
相同?
这里是控制器代码:
<?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');
}
}
?>
和图库模型:
<?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'];
}
?>
和迁移函数:
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');
});
}
更新
我在迁移功能中看到这个配置有问题,在这里:
$table->timestamp('published_at');
并且这个语句创建了 SQL 这样的:
CREATE TABLE `gallery` (
...
`published_at` Timestamp NOT NULL ON UPDATE CURRENT_TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
...
)
那么,如何设置一个不在当前时间自动更新的时间戳字段?
更新 2
完成,我修改迁移,只用dateTime
代替timestamp
。
使用它,$table->dateTime('published_at');
,此语句不会在 CURRENT_TIMESTAMP.
上自动更新
看起来正在发生的事情是 MySQL(或您正在使用的任何数据库)正在更新日期,而不是 Laravel。
您需要更改:
$table->timestamp('published_at');
至:
$table->dateTime('published_at');
然后执行 php artisan migrate:refresh
回滚并重新创建您的表。
替代解决方案是创建一个迁移,运行 此查询删除列的 ON UPDATE 触发器:
ALTER TABLE queued_posts CHANGE scheduled_publish_time scheduled_publish_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
这个 Post 是旧的,但对于任何遇到此问题的人来说,这里是最简单的解决方案。在您的迁移中,时间戳字段必须可以为空。将不会在此字段上触发自动更新。
$table->timestamp('published_at')->nullable();
无需使用 $table->dateTime()
而不是 $table->timestamp()
。
无需将迁移更改为
$table->dateTime('published_at');
就这样吧
$table->timestamp('published_at')->nullable();
要显示日期,您可以在模型中使用类似这样的东西
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;
}
在视图中
Published {{ $post->getShortDateTimeFromTimestamp($post->published_at) }}
要在 storing/updating 资源时使用当前时间戳,您可以使用
published_at = \Carbon\Carbon::now();
这不是Laravel的问题,而是MySQL的"feature"问题。
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.
官方网站删除了旧版本的参考手册,但是当我google解决问题时,从也提到该问题的来源来看,似乎该功能适用于旧版本MySQL也是。
因此,除了将$table->timestamp('published_at');
改为$table->dateTime('published_at');
,您也可以尝试通过
来解决问题
- 给时间戳一个默认值。例如
$table->timestamp('published_at')->default(DB::raw('CURRENT_TIMESTAMP'));
或 $table->timestamp('published_at')->nullable()
(默认值为 null)
- 在
$table->timestamps();
之后移动该行,这样 pulibhsed_at
就不是第一个时间戳。默认的 created_at
和 updated_at
可以为空(即默认值为 null),不会触发 "feature"
我想更新模型上的字段 (status
)。我将从数据库中检索并为 status
列分配一个新值。但是模型保存后,我看到另一个日期字段 (published_at
) 也更改为与 updated_at
相同。
当用户点击 link 作为 http://localhost/dashboard/gallery/publish/1 时的操作 运行。
我不知道为什么 published_at
自动更新并与 updated_at
相同?
这里是控制器代码:
<?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');
}
}
?>
和图库模型:
<?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'];
}
?>
和迁移函数:
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');
});
}
更新
我在迁移功能中看到这个配置有问题,在这里:
$table->timestamp('published_at');
并且这个语句创建了 SQL 这样的:
CREATE TABLE `gallery` (
...
`published_at` Timestamp NOT NULL ON UPDATE CURRENT_TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
...
)
那么,如何设置一个不在当前时间自动更新的时间戳字段?
更新 2
完成,我修改迁移,只用dateTime
代替timestamp
。
使用它,$table->dateTime('published_at');
,此语句不会在 CURRENT_TIMESTAMP.
看起来正在发生的事情是 MySQL(或您正在使用的任何数据库)正在更新日期,而不是 Laravel。
您需要更改:
$table->timestamp('published_at');
至:
$table->dateTime('published_at');
然后执行 php artisan migrate:refresh
回滚并重新创建您的表。
替代解决方案是创建一个迁移,运行 此查询删除列的 ON UPDATE 触发器:
ALTER TABLE queued_posts CHANGE scheduled_publish_time scheduled_publish_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
这个 Post 是旧的,但对于任何遇到此问题的人来说,这里是最简单的解决方案。在您的迁移中,时间戳字段必须可以为空。将不会在此字段上触发自动更新。
$table->timestamp('published_at')->nullable();
无需使用 $table->dateTime()
而不是 $table->timestamp()
。
无需将迁移更改为
$table->dateTime('published_at');
就这样吧
$table->timestamp('published_at')->nullable();
要显示日期,您可以在模型中使用类似这样的东西
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;
}
在视图中
Published {{ $post->getShortDateTimeFromTimestamp($post->published_at) }}
要在 storing/updating 资源时使用当前时间戳,您可以使用
published_at = \Carbon\Carbon::now();
这不是Laravel的问题,而是MySQL的"feature"问题。
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.
官方网站删除了旧版本的参考手册,但是当我google解决问题时,从也提到该问题的来源来看,似乎该功能适用于旧版本MySQL也是。
因此,除了将$table->timestamp('published_at');
改为$table->dateTime('published_at');
,您也可以尝试通过
- 给时间戳一个默认值。例如
$table->timestamp('published_at')->default(DB::raw('CURRENT_TIMESTAMP'));
或$table->timestamp('published_at')->nullable()
(默认值为 null) - 在
$table->timestamps();
之后移动该行,这样pulibhsed_at
就不是第一个时间戳。默认的created_at
和updated_at
可以为空(即默认值为 null),不会触发 "feature"