Как заигнорить поведение?

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Ответить
Brainfuck
Сообщения: 313
Зарегистрирован: 2018.02.19, 14:20

Как заигнорить поведение?

Сообщение Brainfuck »

Столкнулся с очень неприятной проблемой при использовании TimestampBehavior. Я переносил данные с нескольких старых баз (сливал в одну с изменением структуры через консольный контроллер) и когда я уже все закончил - заметил что даты проставились везде текущие (такие как created/updated), хотя я их переносил тоже!

Вопрос такой: почему TimestampBehavior не учитывает то что при сохранении у модели уже проставлено значение поля и перезаписывает его? Было бы логично чтобы оно это учитывало для create, а для update там ведь у модели кажется тоже можно посмотреть какие конкретно поля изменились (при сохранении) и соответственно если вручную были установлены значения - то тоже их не перезаписывать. Вот. Это что-то вроде пропозала! :D

Теперь что мне делать в текущей ситуации? Видимо мне придется повторно переносить все данные, но как быть с поведением? Временно закомментировать у всех моделей его? Их довольно много и это не особо удобно, но другого способа обхода я не вижу. :?
DfK
Сообщения: 5
Зарегистрирован: 2018.02.19, 19:59

Re: Как заигнорить поведение?

Сообщение DfK »

Если это на один раз - в миграции сделайте update напрямую в базу и всех дел
Nex-Otaku
Сообщения: 831
Зарегистрирован: 2016.07.09, 21:07

Re: Как заигнорить поведение?

Сообщение Nex-Otaku »

"preserveNonEmptyValues" укажите для TimestampBehavior.
Brainfuck
Сообщения: 313
Зарегистрирован: 2018.02.19, 14:20

Re: Как заигнорить поведение?

Сообщение Brainfuck »

Nex-Otaku писал(а): 2018.02.20, 03:12 "preserveNonEmptyValues" укажите для TimestampBehavior.
Не очень понял по докам он не будет перезаписывать только вручную установленные атрибуты? Или он вообще не будет перезаписывать непустые атрибуты? В смысле он не сломает в принципе TimestampBehavior? Т.е. если модель была загружена методом find например и у нее не меняли даты вручную, но они с прошлого раза были уже непустые то оно их должно перезаписать (ну по крайней мере ту что updated_at)!
andku83
Сообщения: 988
Зарегистрирован: 2016.07.01, 10:24
Откуда: Харьков

Re: Как заигнорить поведение?

Сообщение andku83 »

перед сохранением отключить поведение:

Код: Выделить всё

$model->detachBehavior('');
Brainfuck
Сообщения: 313
Зарегистрирован: 2018.02.19, 14:20

Re: Как заигнорить поведение?

Сообщение Brainfuck »

Кстати да, я проверил: preserveNonEmptyValues полностью ломает TimestampBehavior. Так что не пойдет так.

Кстати $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
Правда $model->detachBehaviors() работает в то же время. Так что хз. Может $model->detachBehavior надо как-то по другому вызывать?
Brainfuck
Сообщения: 313
Зарегистрирован: 2018.02.19, 14:20

Re: Как заигнорить поведение?

Сообщение Brainfuck »

Кажется понял: я в модели в методе behaviors возвращал массив строк (или массив массивов):

Код: Выделить всё

public function behaviors()
{
    return [
        TimestampBehavior::class,
        [
            'class' => TimestampBehavior::class
        ]
    ];
}
А надо было с ключом это делать:

Код: Выделить всё

public function behaviors()
{
    return [
        'timestamp' => TimestampBehavior::class,
        'timestamp' => [
            'class' => TimestampBehavior::class
        ]
    ];
}
Тогда можно написать $model->detachBehavior('timestamp') (и это сработает)
andku83
Сообщения: 988
Зарегистрирован: 2016.07.01, 10:24
Откуда: Харьков

Re: Как заигнорить поведение?

Сообщение andku83 »

Brainfuck писал(а): 2018.02.20, 16:40 Тогда можно написать $model->detachBehavior('timestamp') (и это сработает)
хорошо когда думают :)
Ответить