【发布时间】:2015-07-05 08:39:03
【问题描述】:
我只想使用 created_at ,怎么办?
我知道:
这可以自定义时间戳名称
const CREATED_AT = 'created';
const UPDATED_AT = 'updated';
这可以禁用时间戳
public $timestamps = false;
【问题讨论】:
我只想使用 created_at ,怎么办?
我知道:
这可以自定义时间戳名称
const CREATED_AT = 'created';
const UPDATED_AT = 'updated';
这可以禁用时间戳
public $timestamps = false;
【问题讨论】:
Eloquent 不提供开箱即用的此类功能,但您可以使用 creating 事件回调自行创建:
class User extends Eloquent {
public $timestamps = false;
public static function boot()
{
parent::boot();
static::creating(function ($model) {
$model->created_at = $model->freshTimestamp();
});
}
}
【讨论】:
parent::boot();。
$model->setCreatedAt($model->freshTimestamp());,这将使用static::CREATED_AT const
$table->timestamp('created_at')->useCurrent(); 来跳过引导代码
static::creating(function ($model) { if (! $model->isDirty(static::CREATED_AT)) { $model->created_at = $model->freshTimestamp(); } });
我的解决方案是使用新的__construct 方法。
见:
class MyModel extends Eloquent {
public $timestamps = false;
public function __construct(array $attributes = [])
{
parent::__construct($attributes);
$this->attributes['created_at'] = $this->freshTimestamp();
}
}
【讨论】:
我的解决方案:
class CreatePostsTable extends Migration {
public function up() {
Schema::create('posts', function(Blueprint $table){
$table->timestamp('created_at')->default(DB::raw('CURRENT_TIMESTAMP'));
});
}
这对我有用
【讨论】:
Carbon::setTestNow($now);
$table->timestamp('created_at')->useCurrent();
要仅禁用 updated_at,您可以覆盖 Model::setUpdatedAt() 方法,如下所示:
public function setUpdatedAt($value) {
// Do nothing.
}
当然,如果您想对 created_at 列执行此操作,也同样简单。这适用于 Laravel 5.1
【讨论】:
return Arr::add($values, $column, $this->model->freshTimestampString()); 时更新时间戳
function setUpdatedAtAttribute($value)CMIIW
const UPDATED_AT = null;
仅使用 setUpdatedAt 的方法不适用于 Laravel 5.1.7,因为它还有一个处理 updated_at 的地方。
Model类performUpdate方法调用Builder类方法:
public function update(array $values)
{
return $this->query->update($this->addUpdatedAtColumn($values));
}
这导致我们
return Arr::add($values, $column, $this->model->freshTimestampString());
我不确定,为什么 Laravel 处理 updated_at 两次 - 在 performUpdate 和 $this->updateTimestamps() 中,然后在 Builder 中使用 $this->addUpdatedAtColumn($values)。
通过一些调试,我发现您还必须使用 getUpdatedAtColumn 覆盖更新您的模型。一开始我还担心它会尝试更新一个不存在的字段“null”,但事实证明Arr::add 足够聪明,可以忽略空键。
所以,在你的模型类中添加这些:
public function setUpdatedAt($value)
{
// Do nothing.
}
public function getUpdatedAtColumn()
{
return null;
}
这应该足以禁用这两个更新。
【讨论】:
null:public function getDates() { $defaults = [static::CREATED_AT]; return $this->timestamps ? array_merge($this->dates, $defaults) : $this->dates; }
在顶部使用:
const UPDATED_AT = null;
对于“created_at”字段,您可以使用:
const CREATED_AT = null;
LARAVEL 5.5.0 - 5.5.5 更新
这已被破坏in Laravel 5.5.0(并再次修复in 5.5.5)。
如果您使用的是 5.5.x,请确保您使用的是最新版本。
如果由于某种原因您无法使用最新版本,这里有一个解决方法。
将公共 $timestamps 设置为 false:
public $timestamps = false;
必要时:
public function setCreatedAtAttribute($value) {
$this->attributes['created_at'] = \Carbon\Carbon::now();
}
或
public function setUpdatedAtAttribute($value) {
$this->attributes['updated_at'] = \Carbon\Carbon::now();
}
当需要“created_at”和“updated_at”这两个字段时,当然不必做任何事情;)
【讨论】:
const UPDATED_AT = null; 阻止 Laravel 尝试更新表中的 updated_at 字段。
if (! is_null(static::UPDATED_AT) && 好吧,他/她使用源代码是正确的,但他/她在政治上不正确地称呼人名。
here 为Laravel 5.2 or above 提供了更好的答案。
你可以在模型中使用它-
class User extends Model
{
public $timestamps = false; // disable all behavior
public $timestamps = true; // enable all behavior
public $timestamps = [ "created_at" ]; // enable only to created_at
public $timestamps = [ "updated_at" ]; // enable only to updated_at
public $timestamps = [ "created_at", "updated_at" ]; // same as true, enable all behavior
}
所以,对于你的问题,答案是 -
public $timestamps = [ "created_at" ]; // enable only to created_at
public $timestamps = [ "created_at" ];
不适用于 Laravel 6+
【讨论】:
Column not found: 1054 Unknown column 'updated_at' in 'field list'
我使用了非常简单的 hack ;)
类 MyClass 扩展模型 {
const CREATED_AT = 'creation_date';
const UPDATED_AT = 'creation_date';
}
我只是将两者都指向同一列:)
【讨论】:
在 5.3 版中,我只是做了public $timestamps = false;,然后添加了受保护的 $fillable = ['created_at']。注意:你可以添加任何你想要的东西,只要确保它与你表中的匹配即可。`
【讨论】:
一个简单、解耦和可重用的解决方案是使用模型观察器。这个想法是捕获creating 事件并填充created_at 属性。这种方法可以被任意数量的模型使用,而无需重复代码或使用非官方的技巧。最重要的是,它与 Model 类的内部机制非常相似,从而避免了意外错误。
1) 在App\Observers 中创建SetCreatedAt 观察者:
namespace App\Observers;
use Illuminate\Database\Eloquent\Model;
class SetCreatedAt
{
/**
* Sets created_at when creating the model.
*
* @param Model $model
* @return void
*/
public function creating(Model $model)
{
$model->setCreatedAt($model->freshTimestamp());
}
}
2) 在boot 方法内的App\Providers\AppServiceProvider 上,为您希望为其生成created_at 的每个模型添加以下行:
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
// Replace OrderLog with your model
OrderLog::observe(SetCreatedAt::class);
}
3) 在您的模型上,您唯一需要做的就是禁用时间戳:
// Disable timestamps on the model
public $timestamps = false;
使用 Laravel 5.3 进行测试,但它也应该适用于以前的版本。
祝你好运!
【讨论】:
YourModel::observe(SetCreatedAt::class) 行。我这里写了更详细的教程arianacosta.com/php/laravel/…
在 5.4 中,它给出的问题是即使在更新(Eloquent 更新)之后它也不会填充 updated_at 字段。
改为添加此方法
public function setUpdatedAtAttribute($value)
{
// auto disable update_at in inserts
}
【讨论】:
我通过在我的数据库中为列created_at 添加默认值CURRENT_TIMESTAMP 来解决。在我的模型中,我使用下面的代码
public $timestamps = false;
protected $dates = ['created_at'];
我希望这个方法适用于所有版本的 laravel。
【讨论】:
您可以在 MySQL 表中为 created 字段使用 CURRENT_TIMESTAMP 默认值并设置
public $timestamps = false;
在你的模型中。
【讨论】:
在类的顶部使用:
const UPDATED_AT = null;
或
const CREATED_AT = null;
【讨论】:
在 Laravel 5.7 中,这对我来说已经足够了:
迁移中:
$table->timestamp('created_at')->nullable();
而不是经典的$table->timestamp('created_at');
在模型中:
const UPDATED_AT = null;
【讨论】:
在您的model 设置上
const UPDATED_AT = null;
或
const CREATED_AT = null;
它会阻止 Laravel 尝试更新 updated_at/created_at 字段
适用于 Laravel 5.8
而且它比覆盖:setUpdatedAt 在你的model 中更好
public function setUpdatedAt($value) : self
{
// Do nothing.
return $this;
}
因为它更短并且因为if (! is_null(static::UPDATED_AT) 的检查在源代码中发生在触发之前
setUpdatedAt
【讨论】:
自 Laravel 5.*
型号:
// Disable updated_at (only created_at)
class Book extends Model
{
const UPDATED_AT = null;
/* ... */
}
迁移:
Schema::create('books', function (Blueprint $table): void {
/* ... */
$table->timestampTz('created_at')->nullable();
});
【讨论】:
对于在这里寻找updated_at 而不是created_at 的任何人,但其他答案似乎都不适合您:
在 Laravel 8 中,您需要将模型属性 CREATED_AT 设置为 null 并将 UPDATED_AT 设置为“updated_at”或您想要的任何其他名称到您的 updated_at 字段。
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
/**
* The name of the "created at" column.
*
* @var string|null
*/
const CREATED_AT = null;
/**
* The name of the "updated at" column.
*
* @var string|null
*/
const UPDATED_AT = 'updated_at';
public function setCreatedAt($value)
{
// do nothing
}
}
还有你的迁移...
Schema::create('users', function (Blueprint $table) {
// ...
$table->timestamp('updated_at'); // instead of $table->timestamps();
});
我不确定为什么需要在模型中设置此属性,因为它已经在父类 Illuminate\Database\Eloquent\Model 中设置,但它仅在我进行此更改后才对我有用。
【讨论】: