情境:我有一个模型(让我们称之为Pivot
),声明如下:
class Pivot extends Model
{
public $timestamps = false;
.....
}
它有5个字段:id
,notification_id
,device_id
,created_at
,read_at
。
此模型用作Notification
和Device
之间的数据透视表:
// Notification.php
public function devices()
{
return $this->belongsToMany(Device::class)
->withPivot(['id','created_at','notification_id','device_id', 'read_at']);
}
public function pivots() {
return $this->hasMany(Pivot::class);
}
我在Device类中做了同样的事情。
我的MySQL的时区(Europe\Rome
)与UTC不同,我无法更改它,因为它已被不同项目使用。
问题:如何设置created_at
字段才能正常工作?
我尝试使用默认时间戳,它可以工作但是它还会添加updated_at
列而我无法使用它(它会添加太多冗余)。
所以我设置了public $timestamps = false;
,我在数据库中创建了这样的字段:
$table->timestamp('created_at')->default(DB::raw('CURRENT_TIMESTAMP'));
这个问题的原因在于,如前所述,MySQL的时区错误(Europe\Rome
),所以当我从这个表中读取数据时,created_at
值会从原版的。当我还设置read_at
属性时,这是一个问题,因为它会创建在创建之前读取通知的情况。
我的最后一个想法是在创建事件中设置created_at
。我跟着this laracast guide,但显然,如果数据是作为sync
方法的数据透视表插入的,则不会调用事件(它们对我没有用)。
你有其他想法吗?当然有一些丑陋的黑客可以工作(比如在创建的Pivot
上迭代并手动设置它们),但我想使用更好的解决方案。
config/database.php
中设置了MySQL配置数组的timezone属性:
'mysql' => [
'driver' => 'mysql',
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'strict' => true,
'engine' => null,
'timezone' => '+00:00',
],
答案 0 :(得分:0)
使用model events设置创建模型时的时间戳。您可以将字段和时区设置在一起。
class Pivot extends Model
{
public $timestamps = false;
protected static function boot()
{
static::creating(function($model) {
$model->create_at = Carbon::now('Europe\Rome');
});
parent::boot();
}
}
不要忘记parent::boot()
,否则将无法在模型上启动特征。