MacFiss
@MacFiss
человек

Как правильно оптимизировать связи в Yii2?

Доброго вечера. Есть три таблицы:
1) users [id, site_id]
2) users_fields [id, user_id, site_id]
3) users_fields_value [id, user_id, field_id]

Правильный SQL который необходимо перевести в логику связей Yii2 (getFieldValue):
select 
users.id,
users_fields.name,
users_fields_value.value
from `users`
join `users_fields` on users.site_id=users_fields.site_id
left join `users_fields_value` on users_fields.id=users_fields_value.field_id
and users_fields_value.user_id=users.id
where users.site_id=14

Достаточно указать идентификатор сайта и будет сделана выгрузка всех дополнительных полей и их значений
+ and users.id=X <- выгрузка определенного пользователя у сайта и его доп.полей

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

Сейчас работает все вот так: на каждого пользователя делается один запрос на выборку доп.полей, а потом и их значений. В итоге кол-во запросов в бд зашкаливает...

public function getListUsers($site_id) 
{
        if( ! ( $userModel = Site::findModel($site_id) ) ) {
            return false;
        }
       $models = $userModel->getUsers()
                    ->where([
                        'status' => 1
                    ])
                    ->all();

        if( ! $models ) {
            throw new NotFoundHttpException('Users not found');
        }

        $result = [];

        foreach($models as $model) {
            $result[] = [
                'name' => $model->name,
                'other' => $this->getArrayFieldValues($model->fields, $model->id)
            ];
        }
        
        return $result;
}

private function getArrayFieldValues(array $models, int $user_id)
    {
        $result = [];

        foreach ($models as $model) {
            if( ! ($value = $model->getFieldValue($user_id)->one()) ) {
                continue;
            }

            $result[$model->name] = $value->value;
        }

        return ! empty($result) ? $result : false;
    }


model Site.php:
public static function findModel($id)
    {
        if( ! ($model = self::findOne($id)) ) {
            throw new NotFoundHttpException(Yii::t('sites', 'Website is not found'));
        }

        return $model;
    }

public function getUsers()
    {
        return $this->hasMany(Users::className(), ['site_id' => 'id']);
    }


model Users.php
public function getFields()
    {
        return $this->hasMany(UsersFields::className(), ['site_id' => 'site_id']);
    }


model UsersFields.php
public function getFieldsValue()
    {
        return $this->hasMany(UsersFieldsValue::className(), ['field_id' => 'id']);
    }

    public function getFieldValue($user_id)
    {
        return $this->getFieldsValue()
                    ->where(['user_id' => $user_id]);
    }
  • Вопрос задан
  • 164 просмотра
Пригласить эксперта
Ответы на вопрос 1
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы