afterFind && beforeSave

Общие вопросы по использованию фреймворка. Если не знаете как что-то сделать и это про Yii, вам сюда.
Ответить
big_mike
Сообщения: 113
Зарегистрирован: 2013.02.26, 01:12

afterFind && beforeSave

Сообщение big_mike »

Возникла проблема следующего плана. Есть 2 триггера:

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

public function afterFind()
    {
        $this->create_time = DateHelper::formatDate($this->create_time, 'short');      
    }

    protected function beforeSave()
    { 
        if (parent::beforeSave()) {
            if ($this->isNewRecord) {
                $this->create_time = time();                
            } 
            return true;
        } else
            return false;
    } 
Так вот, при каждом сохранении модели, поле create_time постоянно сбрасывается (там, то 1, то 4). Если закоментить afterFind, то все нормально. В чем загвоздка?
Аватара пользователя
futbolim
Сообщения: 2051
Зарегистрирован: 2012.07.08, 19:28

Re: afterFind && beforeSave

Сообщение futbolim »

afterFind должен вернуть true
big_mike
Сообщения: 113
Зарегистрирован: 2013.02.26, 01:12

Re: afterFind && beforeSave

Сообщение big_mike »

Не помогло =( Заметил еще одно, если поставить:

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

array('create_time', 'integerOnly' => true), 
И попытаться сохранить модель, выводится ошибка, что дата создания не число О_о. Т.е., если я верно понимаю срабатывает:

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

$this->create_time = MainHelper::formatDate($this->create_time, 'short'); 
С какой такой радости :!: :?:
Аватара пользователя
ElisDN
Сообщения: 5845
Зарегистрирован: 2012.10.07, 10:24
Контактная информация:

Re: afterFind && beforeSave

Сообщение ElisDN »

Как с какой радости? afterFind и должен каждый раз срабатывать.
masson
Сообщения: 545
Зарегистрирован: 2012.07.03, 15:59

Re: afterFind && beforeSave

Сообщение masson »

Если значение create_time после создания нигде больше меняться не должно - лучше форматить не в afterFind, а прямо во вьюхах, в полях вывода. value=DateHelper::formatDate($this->create_time, 'short')
А если нужно менять - то в beforeSave, в блоке !isNewRecord надо форматить обратно $this->create_time в число
codrilla
Сообщения: 173
Зарегистрирован: 2013.03.06, 12:24
Откуда: Молдова, Тирасполь

Re: afterFind && beforeSave

Сообщение codrilla »

То есть код у вас должен выглядеть таким образом:

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

public function afterFind()
    {
        $this->create_time = DateHelper::formatDate($this->create_time, 'short');      
    }

    protected function beforeSave()
    { 
        if (parent::beforeSave()) {
            if ($this->isNewRecord) {
                $this->create_time = time();                
            } else {
                // конвертирование $this->create_time обратно в юникс-время 
            }
            return true;
        } else 
            return false;
    }
Но правильно вам сказали, конвертировать надо во view
masson
Сообщения: 545
Зарегистрирован: 2012.07.03, 15:59

Re: afterFind && beforeSave

Сообщение masson »

Можно так. Но если дату-время нужно показывать и при создании новых записей тоже, я бы сделал так (примерно) :

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

    public $innerDate;             // Поле БД
    public $displayedDate;         // Доп.св-во для отображения на формах и редактирования

    public function rules() {
        return array('displayedDate', 'safe');     // или к-л валидатор, если нужны проверки значения
    }

    
    public function afterConstruct() {
        $this->displayedDate = date('d.m.Y', time());    // Форматируем дату при создании новой записи
        parent::afterConstruct();
    }

    
    public function afterFind() {
        $this->displayedDate = date('d.m.Y', $this->innerDate);    // Форматируем дату при выборке записи из БД
        parent::afterFind();
    }
   
    public function beforeSave() {
        if(!parent::beforeSave()) 
            return false;

        $this->innerDate = strtotime($this->displayedDate);     // Возвращаем дату в unixtime перед сохранением
        return true;
    } 
Во вьюхах выводим $this->displayedDate без к-л доп.преобразований, уже все готово.
Тогда это значение еще и редактировать можно, каким-нибудь датапикером.
big_mike
Сообщения: 113
Зарегистрирован: 2013.02.26, 01:12

Re: afterFind && beforeSave

Сообщение big_mike »

ElisDN писал(а):Как с какой радости? afterFind и должен каждый раз срабатывать.
Так данные же записываются, а не получаются, должно же быть сначала по логике вещей beforeSave, а потом afterFind, что я не так понимаю, разжуйте?
masson
Сообщения: 545
Зарегистрирован: 2012.07.03, 15:59

Re: afterFind && beforeSave

Сообщение masson »

При редактировании - сначала получаются (find), потом изменяются (attributes = POST), потом измененные записываются взат (save)
Аватара пользователя
ElisDN
Сообщения: 5845
Зарегистрирован: 2012.10.07, 10:24
Контактная информация:

Re: afterFind && beforeSave

Сообщение ElisDN »

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

$model = Post::model()->findByPk($id); // здесь находится запись и срабатывает afterFind
$model->attributes = $_POST['Post'];
$model->save(); // здесь beforeValidate, afterValidate, beforeSave, сохранение и afterSave   

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

$model = new Post(); // здесь ничего
$model->attributes = $_POST['Post'];
$model->save(); // здесь beforeValidate, afterValidate, beforeSave, сохранение и afterSave   
big_mike
Сообщения: 113
Зарегистрирован: 2013.02.26, 01:12

Re: afterFind && beforeSave

Сообщение big_mike »

Всем спасибо, все стало на свои места
masson
Сообщения: 545
Зарегистрирован: 2012.07.03, 15:59

Re: afterFind && beforeSave

Сообщение masson »

ElisDN писал(а):

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

$model = new Post(); // здесь ничего   
Здесь afterConstruct()
Ответить