asArray и виртуальные атрибуты
asArray и виртуальные атрибуты
добрый день,
подскажите, пожалуйста, реализацию переопределенной функции asArray, чтобы подтягивать виртуальные атрибуты модели.
p.s. делается для оптимизации, т.к. ООП ресурсы сильно кушает
подскажите, пожалуйста, реализацию переопределенной функции asArray, чтобы подтягивать виртуальные атрибуты модели.
p.s. делается для оптимизации, т.к. ООП ресурсы сильно кушает
- samdark
- Администратор
- Сообщения: 9489
- Зарегистрирован: 2009.04.02, 13:46
- Откуда: Воронеж
- Контактная информация:
Re: asArray и виртуальные атрибуты
Покажите, как вы хотите этот метод использовать. И расскажите, что вы понимаете под виртуальными атрибутами.
Нравится Yii? Давайте сделаем его лучше!.
Re: asArray и виртуальные атрибуты
к примеру,
в модели есть атрибут fullName, который получается конкатенацией фамилией и именем на нужном языке. Производим выборку нескольких моделей с зависимостью:
и чтобы можно было во view получить доступ к к атрибуту fullName
в модели есть атрибут fullName, который получается конкатенацией фамилией и именем на нужном языке. Производим выборку нескольких моделей с зависимостью:
Код: Выделить всё
$models = Employeer::find()
->crew()
->with('rank')
->orderBy(['updated_at' => SORT_DESC])
->limit(Yii::$app->config->get('elementsInPanel'))
->asArray()
->all();
Код: Выделить всё
$model['fullName']
Re: asArray и виртуальные атрибуты
я так понмиаю, вам нужен метод fields(), который как раз к результату asArray подмешивает любые атрибуты.
https://github.com/yiisoft/yii2/blob/36 ... ng-fields-
https://github.com/yiisoft/yii2/blob/36 ... ng-fields-
Re: asArray и виртуальные атрибуты
не совсем то, получается надо делать запрос без asArray. И потом результат перебирать в foreach и преобразовывать модель в массив с помощью toArray.zelenin писал(а):я так понмиаю, вам нужен метод fields(), который как раз к результату asArray подмешивает любые атрибуты.
https://github.com/yiisoft/yii2/blob/36 ... ng-fields-
- samdark
- Администратор
- Сообщения: 9489
- Зарегистрирован: 2009.04.02, 13:46
- Откуда: Воронеж
- Контактная информация:
Re: asArray и виртуальные атрибуты
zelenin, asArray не инстранциирует модель.
Нравится Yii? Давайте сделаем его лучше!.
Re: asArray и виртуальные атрибуты
ну ему и не нужен инстанс, ему нужен массив с полем.Sam Dark писал(а):zelenin, asArray не инстранциирует модель.
Re: asArray и виртуальные атрибуты
не знаю, может как вариант. Написать что-то типа Хелпера под модель. И вызывать его методы для обработки как в геттере модели, так и при обработке данных массиваSam Dark писал(а):zelenin, asArray не инстранциирует модель.
так не получится вызвать метод без инстансаzelenin писал(а):ну ему и не нужен инстанс, ему нужен массив с полем.
Re: asArray и виртуальные атрибуты
по ссылке примерde1phi писал(а):не знаю, может как вариант. Написать что-то типа Хелпера под модель. И вызывать его методы для обработки как в геттере модели, так и при обработке данных массиваSam Dark писал(а):zelenin, asArray не инстранциирует модель.
так не получится вызвать метод без инстансаzelenin писал(а):ну ему и не нужен инстанс, ему нужен массив с полем.
Код: Выделить всё
public function fields()
{
return [
// field name is the same as the attribute name
'id',
// field name is "email", the corresponding attribute name is "email_address"
'email' => 'email_address',
// field name is "name", its value is defined by a PHP callback
'name' => function ($model) {
return $model->first_name . ' ' . $model->last_name;
},
];
}
- samdark
- Администратор
- Сообщения: 9489
- Зарегистрирован: 2009.04.02, 13:46
- Откуда: Воронеж
- Контактная информация:
Re: asArray и виртуальные атрибуты
fields работает если у нас есть инстанс и мы делаем toArray. Это не asArray. Весь смысл затеи автора топика — не инстанциировать объект класса для сохранения ресурсов.
Нравится Yii? Давайте сделаем его лучше!.
Re: asArray и виртуальные атрибуты
ага, понятно. спутал toArray и asArray.Sam Dark писал(а):fields работает если у нас есть инстанс и мы делаем toArray. Это не asArray. Весь смысл затеи автора топика — не инстанциировать объект класса для сохранения ресурсов.
Re: asArray и виртуальные атрибуты
ну надо полагать у тебя аттрибут конкатенацию в afterFind делает
а соласно коду https://github.com/yiisoft/yii2/blob/36 ... y.php#L225 при asArray afterFind не выполняется
а соласно коду https://github.com/yiisoft/yii2/blob/36 ... y.php#L225 при asArray afterFind не выполняется
Re: asArray и виртуальные атрибуты
зачем? обычным геттеромInsolita писал(а):ну надо полагать у тебя аттрибут конкатенацию в afterFind делает
а соласно коду https://github.com/yiisoft/yii2/blob/36 ... y.php#L225 при asArray afterFind не выполняется
Re: asArray и виртуальные атрибуты
если именно нужно имя + фамилию то как-то так
а про геттеры и сеттеры модели при asArray тем более ничего не знает https://github.com/yiisoft/yii2/blob/36 ... t.php#L111
Код: Выделить всё
$query->select(['{{%table}}.*', new Expression('CONCAT_WS({{%table}}.name, {{%table}}.surname, " ") as fullName')])
Re: asArray и виртуальные атрибуты
это все хорошо я обрисовал самый простой пример. Но в модели же полно других геттеровInsolita писал(а):если именно нужно имя + фамилию то как-то така про геттеры и сеттеры модели при asArray тем более ничего не знает https://github.com/yiisoft/yii2/blob/36 ... t.php#L111Код: Выделить всё
$query->select(['{{%table}}.*', new Expression('CONCAT_WS({{%table}}.name, {{%table}}.surname, " ") as fullName')])
поэтому все-таки склоняюсь к хелперу...
p.s. хотя тоже не вариант, в модели же есть константы и т.д. =( похоже придется дублировать код
- samdark
- Администратор
- Сообщения: 9489
- Зарегистрирован: 2009.04.02, 13:46
- Откуда: Воронеж
- Контактная информация:
Re: asArray и виртуальные атрибуты
Не статические методы модели без экземпляра класса модели не вызвать. Так что да, либо в статику выносить, либо дублировать.
Нравится Yii? Давайте сделаем его лучше!.
Re: asArray и виртуальные атрибуты
ну так как при asArray инстансов модели вообще не создается - соответственно нет возможности обратится к модели и узнать аттрибуты поэтому хелпер тут не поможет ... из того что навскидку - в модели создать метод типа virtfields() по аналогии с fields
и расширить ActiveQuery с переопределением метода populate
ну и в модели соответственно использовать нужный ActiveQuery
в общем у меня отработало, правда еще надо тестировать чтоб другие никакие запросы не использовало
Код: Выделить всё
public static function virtFields(){
return [
'fullName'=>function($model){return $model['name'].' '.$model['surname'];}
];
}
Код: Выделить всё
public function populate($rows){
$models=parent::populate($rows);
if(!$this->asArray){
return $models;
}else{
$class = $this->modelClass;
$dopfields=method_exists($class, 'virtFields')?$class::virtFields():[];
foreach ($models as &$model) {
if(!empty($dopfields)){
foreach($dopfields as $attr=>$val){
if(is_string($val)){
$model=array_merge($model,[$attr=>$val]);
}elseif(is_callable($val)){
$model=array_merge($model,[$attr=>call_user_func($val, $model)]);
}
}
}
}
return $models;
}
}
Код: Выделить всё
/**
* @inheritdoc
* @return ActiveQuery
*/
public static function find()
{
return new MyActiveQuery(get_called_class());
}
Последний раз редактировалось Insolita 2015.01.27, 19:45, всего редактировалось 3 раза.
Re: asArray и виртуальные атрибуты
Insolita спасибо, но по использованию ресурсов почти тоже самое, что и toArray =(
Re: asArray и виртуальные атрибуты
ну чтоб избавиться от еще одного перебора - это уже в ActiveQueryTrate надо лезть... а что большой объем данных в выборках? может не это место ресурсы кушает? (в любом случае это явно менее жирно чем AR - модели) - ресурсы в плане памяти? в production режиме тоже?
Re: asArray и виртуальные атрибуты
больше 8000 записей надо вывести