Как заигнорить поведение?
Как заигнорить поведение?
Столкнулся с очень неприятной проблемой при использовании TimestampBehavior. Я переносил данные с нескольких старых баз (сливал в одну с изменением структуры через консольный контроллер) и когда я уже все закончил - заметил что даты проставились везде текущие (такие как created/updated), хотя я их переносил тоже!
Вопрос такой: почему TimestampBehavior не учитывает то что при сохранении у модели уже проставлено значение поля и перезаписывает его? Было бы логично чтобы оно это учитывало для create, а для update там ведь у модели кажется тоже можно посмотреть какие конкретно поля изменились (при сохранении) и соответственно если вручную были установлены значения - то тоже их не перезаписывать. Вот. Это что-то вроде пропозала!
Теперь что мне делать в текущей ситуации? Видимо мне придется повторно переносить все данные, но как быть с поведением? Временно закомментировать у всех моделей его? Их довольно много и это не особо удобно, но другого способа обхода я не вижу.
Вопрос такой: почему TimestampBehavior не учитывает то что при сохранении у модели уже проставлено значение поля и перезаписывает его? Было бы логично чтобы оно это учитывало для create, а для update там ведь у модели кажется тоже можно посмотреть какие конкретно поля изменились (при сохранении) и соответственно если вручную были установлены значения - то тоже их не перезаписывать. Вот. Это что-то вроде пропозала!
Теперь что мне делать в текущей ситуации? Видимо мне придется повторно переносить все данные, но как быть с поведением? Временно закомментировать у всех моделей его? Их довольно много и это не особо удобно, но другого способа обхода я не вижу.
Re: Как заигнорить поведение?
Если это на один раз - в миграции сделайте update напрямую в базу и всех дел
Re: Как заигнорить поведение?
"preserveNonEmptyValues" укажите для TimestampBehavior.
Re: Как заигнорить поведение?
Не очень понял по докам он не будет перезаписывать только вручную установленные атрибуты? Или он вообще не будет перезаписывать непустые атрибуты? В смысле он не сломает в принципе TimestampBehavior? Т.е. если модель была загружена методом find например и у нее не меняли даты вручную, но они с прошлого раза были уже непустые то оно их должно перезаписать (ну по крайней мере ту что updated_at)!
Re: Как заигнорить поведение?
перед сохранением отключить поведение:
Код: Выделить всё
$model->detachBehavior('');
Re: Как заигнорить поведение?
Кстати да, я проверил: preserveNonEmptyValues полностью ломает TimestampBehavior. Так что не пойдет так.
Кстати $model->detachBehavior тоже не работает! Я проверил:
Правда $model->detachBehaviors() работает в то же время. Так что хз. Может $model->detachBehavior надо как-то по другому вызывать?
Кстати $model->detachBehavior тоже не работает! Я проверил:
Код: Выделить всё
$u = User::findOne(1);
$u->detachBehavior(TimestampBehavior::class);
$u->generateAuthKey();
$old_updated_at = $u->updated_at;
$u->save(false);
echo "\nold_updated_at == new_updated_at: " . ($old_updated_at == $u->updated_at ? 'true' : 'false') . "\n"; // false
Re: Как заигнорить поведение?
Кажется понял: я в модели в методе behaviors возвращал массив строк (или массив массивов):
А надо было с ключом это делать:
Тогда можно написать $model->detachBehavior('timestamp') (и это сработает)
Код: Выделить всё
public function behaviors()
{
return [
TimestampBehavior::class,
[
'class' => TimestampBehavior::class
]
];
}
Код: Выделить всё
public function behaviors()
{
return [
'timestamp' => TimestampBehavior::class,
'timestamp' => [
'class' => TimestampBehavior::class
]
];
}