【问题标题】:Custom created_at attribute on a pivot Model枢轴模型上的自定义 created_at 属性
【发布时间】:2017-07-28 16:27:30
【问题描述】:

情况:我有一个模型(我们称之为Pivot),声明如下:

class Pivot extends Model
{
    public $timestamps = false;
    .....
}

它有 5 个字段:idnotification_iddevice_idcreated_atread_at

此模型用作NotificationDevice 之间的数据透视表:

// 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 的值从原始值偏移了 2 小时。当我还设置 read_at 属性时,这是一个问题,因为它会创建在创建之前读取通知的情况。

我最后的想法是在创建事件中设置created_at。我关注了this laracast guide,但显然,如果将数据作为来自sync 方法的数据透视表插入,则不会调用事件(它们对我不起作用)。

您还有其他想法吗?当然有一些丑陋的黑客可以工作(比如迭代创建的Pivot 并手动设置它们),但我想使用更好的解决方案。

编辑:@Maraboc 提出的解决方案效果很好。我在config/database.php中设置了MySQL配置数组的时区属性:

'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',
    ],

【问题讨论】:

  • 仅在当前 laravel 项目中更改时区怎么样?在config/database.php'mysql' => [ 'driver' => 'mysql',....,'timezone' => '+00:00']
  • 我会试试看的!
  • 有效吗?
  • 是的,它有效。谢谢!

标签: laravel pivot-table laravel-5.4 php-carbon


【解决方案1】:

在创建模型时使用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(),否则模型将不会启动任何特征。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-02
    • 2021-01-08
    • 1970-01-01
    • 1970-01-01
    • 2023-03-27
    • 1970-01-01
    相关资源
    最近更新 更多