Страница 1 из 1

Новое поле в модели

Добавлено: 2019.04.28, 21:47
NeverDie
Здравствуйте!
У меня в модели есть поле date_of_birth. Я хочу, на страницу выводить не только дату рождения но и сколько полных лет сейчас. Так же хочу сделать фильтр по нему через GridView.

Мой вариант сейчас такой.
В модели MyModel я создал такую ф-цию:
class MyModel
{
...
public function getAge()
{
$difference = time() - strtotime($this->date_of_birth);
return floor($difference / 31556926);
}
}
Т.е. технически, через $model->age мы уже можем получить значение.

Для фильтра GridView в MyModelSearch я сделал примерно так:
class MyModelSearch extends MyModel
{
...
public $age;
public function search($params)
{
$query = MyModel::find()->select(['*', 'age' => 'EXTRACT(YEAR FROM age(date_of_birth))']);
...
}
}
У меня есть вопросы в целом по реализации.
1) Можно ли добавить поле динамически в модель (аналогично полю date_of_birth), чтобы оно всегда там было, не писав дополнительно ф-цию getAge()?
Т.е. возможно ли как-то добиться для атрибута age, которого нет в таблице, такого поведения, как если оно есть в таблице?
2) Я пробовал добавлять поле age в fields() в модели.
class MyModel
{
...
public function fields()
{
$fields = parent::fields();
$fields['test'] = $this->getAge();
return $fields;
}
}
При попытка обращения $model = MyModel::findOne(); $model->test в контроллере выдает ошибку, аттрибут не найден. Могли бы вы подробнее объяснить, как работает данный метод? В документации написано, что через него можно создавать дополнительные поля.
https://www.yiiframework.com/doc/guide/ ... ing-fields
Или же данный метод срабатывает только для REST?

Re: Новое поле в модели

Добавлено: 2019.04.29, 10:44
Loveorigami
Все верно Вам пишет. Атрибут не может быть найден, т.к. его нет. В search модели почему то делали все верно, а тут ждете чуда...
Т.е. возможно ли как-то добиться для атрибута age, которого нет в таблице, такого поведения, как если оно есть в таблице?
Все логично и тут - Если ждете поведения, значит поведение нужно создать ;) .

Ну или в методе afterFind реализовать нужную логику для атрибута $test ($age или что вам там нужно).
И совсем уж, чтоб захордкодить, можно пересмотреть (переписать) методы в AR canGetProperty, canSetProperty и магические __get и __set под свои аттрибуты