Изменения в Laravel created_at при обновлении

Я нашел этот ответ по этому вопросу, но он не работает для меня.

Итак, я делаю запись в базе данных:

// Write lead to database
$lead = Lead::create($lead_data);

И временные метки выглядят так, что хорошо:

| 2016-01-08 10:34:15 | 2016-01-08 10:34:15 |

Но затем я делаю запрос на внешний сервер, и мне нужно обновить строку:

$lead->user_id = $response['user_id'];
$lead->broker_id = $response['broker_id'];
$lead->save();

и изменилось поле created_at:

| 2016-01-08 04:34:17 | 2016-01-08 10:34:17 |

Как решить эту проблему?

ИЗМЕНИТЬ

Мне нужно решение, которое просто изменит поведение, не отбрасывая столбцы или перезагружая миграции. Исправление должно выполняться в живой базе данных, не касаясь данных. Как было предложено ниже, я пробовал следующую миграцию:

$table->datetime('created_at')->default(DB::raw('CURRENT_TIMESTAMP'))->change();

но ничего не происходит. Поле created_at по-прежнему изменяется при обновлении.

Ответ 1

Если вы работаете в Laravel 5.2 и используете MySQL, то с метками времени было немного "ошибка". Вы можете прочитать все о проблеме на github здесь. Это связано с параметрами timestamp по умолчанию, и MySQL автоматически назначает атрибуты DEFAULT CURRENT_TIMESTAMP или ON UPDATE CURRENT_TIMESTAMP при определенных условиях.

В принципе, у вас есть три варианта.

  • Обновить переменную MySQL:

Если вы установите для переменной explicit_defaults_for_timestamp значение TRUE, столбцу временной метки не будет присвоен атрибут DEFAULT CURRENT_TIMESTAMP или ON UPDATE CURRENT_TIMESTAMP. Вы можете узнать больше об переменной здесь.

  1. Используйте отметки времени с нулевым значением:

Измените $table->timestamps() на $table->nullableTimestamps(). По умолчанию команда $table->timestamps() создает поля timestamp, которые не имеют значения NULL. Используя $table->nullableTimestamps(), ваши метки timestamp будут иметь значение NULL, и MySQL не будет автоматически назначать первый атрибут DEFAULT CURRENT_TIMESTAMP или ON UPDATE CURRENT_TIMESTAMP.

  1. Определите временные метки самостоятельно:

Вместо $table->timestamps используйте $table->timestamp('updated_at'); $table->timestamp('created_at'); самостоятельно. Убедитесь, что поле "updated_at" является первой временной меткой в ​​таблице, так что это будет тот, который автоматически присваивает атрибуты DEFAULT CURRENT_TIMESTAMP или ON UPDATE CURRENT_TIMESTAMP.

Ответ 2

Skatch - я думаю, что ваше решение выше не совсем правильно, но в этом случае это probaby.

Проблема в том, что вы получаете дату PHP, а не стандартную временную метку MYSQL для своего значения по умолчанию. Когда вы запустите эту миграцию, вы получите следующее выражение:

alter table alter column created_at default '2016:02:01 12:00:00';

Обратите внимание на строку для вашей даты. Когда вы запускаете миграцию, THAT date всегда будет использоваться для вашего created_at, а не текущей даты, когда запись будет добавлена ​​через несколько дней.

Вместо того, чтобы делать "date (" Y: m: d H: i: s "), вы можете сделать DB:: raw ('current_timestamp'), чтобы решить эту проблему.

(sry, не мог просто добавить комментарий выше - моя репутация еще недостаточно высока...)

Ответ 3

Проводя это как ответ верхнего уровня, подведя итоги обсуждения комментариев.

Во-первых, есть дата ошибка, введенная в Laravel - как отмечено @patricus. Предлагаемые решения в обсуждении ошибок - либо использовать nullableTimestamps(), а не только timestamps(), или создавать поля created_at и updated_at напрямую - $table->timestamp('updated_at')->change().

Это также можно исправить с помощью raw SQL. Утверждение ALTER, подобное этому

alter table loader_rawvalues MODIFY column updated_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP

Это может быть применено непосредственно к вашим существующим таблицам БД (сначала проверьте его или курс!). ИЛИ вы можете использовать DB:: unprepared(), чтобы применить его к вашей миграции - например:

class CreateMyTable extends Migration
{
    public function up()
    {
        Schema::create('mytable', function (Blueprint $table) {
            $table->bigIncrements('id');
            // ...
            $table->timestamps();
        });

        DB::unprepared('alter table mytable MODIFY column updated_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP');
    }
}

Ответ 4

Это должно быть проблемой в свойстве поля базы данных. Недавно я столкнулся с той же проблемой, и когда я проверяю свою таблицу, в create_at есть Extra со значением on update CURRENT_TIMESTAMP, чтобы Laravel вел себя нормально, просто обновите определение поля примерно так.

ALTER TABLE table_name CHANGE created_at created_at timestamp NOT NULL default CURRENT_TIMESTAMP;