yii2 как использовать поиск с помощью SqlDataProvider

#php #mysql #yii2

Вопрос:

для моего требования мне нужно использовать SqlDataProvider вместо ActiveDataProvider.

но если я включу поиск, я получу ошибку типа:

 Calling unknown method: yiidataSqlDataProvider::isAttributeRequired() 
 

моя поисковая модель — `userProfileSearch выглядит следующим образом:

 public function search($params)
    {
     //   $query = UserProfile::find()->where($cond);

     $query = new Query;
        $query->select('*')->from('user_profile');
       

        // add conditions that should always apply here

        $dataProvider = new SqlDataProvider([
           // 'query' => $query,
           'sql' => $query->createCommand()->sql,
        ]);

        $this->load($params);

        if (!$this->validate()) {
            // uncomment the following line if you do not want to return any records when validation fails
            // $query->where('0=1');
            return $dataProvider;
        }

        // grid filtering conditions
        $query->andFilterWhere([
            'id' => $this['id'],
            'user_id' => $this['user_id'],
            'pincode' => $this['pincode'],
        ]);

        $query->andFilterWhere(['like', 'first_name', $this['first_name']])
        
            ->andFilterWhere(['like', 'last_name', $this->last_name])
            ->andFilterWhere(['like', 'phone', $this->phone])
            ->andFilterWhere(['like', 'email', $this->email])
            ->andFilterWhere(['like', 'gender', $this->gender])
            ->andFilterWhere(['like', 'skill_level', $this->skill_level])
            ->andFilterWhere(['like', 'play_type', $this->play_type])
            ->andFilterWhere(['like', 'address1', $this->address1])
            ->andFilterWhere(['like', 'address2', $this->address2])
            ->andFilterWhere(['like', 'city', $this->city])
            ->andFilterWhere(['like', 'state', $this->state])
            
            ->andFilterWhere(['like', 'Country', $this->country]);

        return $dataProvider;
    }
 

и в моем контроллере это выглядит так:

 public function actionIndex()
    {
        $count = Yii::$app->db->createCommand('SELECT COUNT(*) FROM user_profile')->queryScalar();
    
    
    $sql= "$sql= "Select user_profile.id as id,
    user_profile.user_id as user_id,
    user_profile.first_name as first_name,
    user_profile.last_name as last_name,
    user_profile.city as city,
    user_profile.pincode as pincode,
    user_profile.profile_image as profile_image,
    user_profile.gender as gender,
    user_profile.play_type as play_type,
    user_profile.skill_level as skill_level,
    ( 3959 * acos 
    (cos ( radians($latitude))
    * cos( radians( latitude )) 
    * cos( radians( longitude) - radians($longitude))
       sin ( radians($latitude) ) 
    * sin( radians( latitude))))
    AS distance
    FROM user_profile
    HAVING distance < 20";";

    $searchModel = new UserProfileSearch();
    $sqlProvider = new SqlDataProvider(['sql'=> $sql]);
    $searchModel = $searchModel->search(Yii::$app->request->queryParams,$sql);

    return $this->render('index', [
        'searchModel' => $searchModel,
        'dataProvider' => $sqlProvider,
    ]);
}
 

Как я могу заставить поиск работать?

Комментарии:

1. SqlDataProvider не основан на модели, поэтому функция, связанная с моделью, как isAttributeRequired, не может работать .. возможно, вы используете где-то какую-то функцию проверки .. но это мне не удалось .. вы должны отменить проверку модели и в конечном итоге выполнить проверку напрямую ..

2. Привет, Скайседж — я использую сгенерированный по умолчанию _search.php для поиска. не используя никаких фильтров. как, например, — <?php $form->field($model, 'gender')->dropDownList(['M'=>'Male','F'=>'Female'],['prompt'=>'Select Gender'])->label(false) ?> это не сработает или где мне нужно внести какие-либо изменения?

Ответ №1:

Я думаю, это потому, что вы переписываете свою переменную $SearchModel с возвращением метода search (), который возвращает SqlDataProvider.

Попробуйте изменить свой контроллер на этот:

 $searchModel = new UserProfileSearch();
$sqlProvider = $searchModel->search(Yii::$app->request->queryParams,$sql);

return $this->render('index', [
    'searchModel' => $searchModel,
    'dataProvider' => $sqlProvider,
]);
 

Ответ №2:

Хотя я не мог решить эту проблему с помощью SqlDataProvider и, конечно, хотел бы знать, как реализовать ее с помощью SqlDataProvider.

Сохраняя все нетронутым из сгенерированного Gii кода, я изменил запрос в UserProfileSearch.php

как показано ниже:

 public function search($params)
    {
        $user = UserProfile::findOne(['user_id'=>Yii::$app->user->identity->id]);       
        
        $latitude = $user->latitude;
        $longitude = $user->longitude;
        $query = UserProfile::find()->select(['id','user_id','first_name','last_name','phone','email','pincode','skill_level','play_type',
        'profile_image','latitude','longitude','gender','city',"( 3959 * acos 
        (cos ( radians($latitude))
        * cos(radians(latitude)) 
        * cos( radians(longitude) - radians($longitude))
           sin (radians($latitude) ) 
        * sin(radians(latitude)))) as distance"]); 
        $query->having(['<','distance', 12.4274]);

        

        $dataProvider = new ActiveDataProvider([
        'query'=>$query           
            
        ]);
 

с этим мой предварительный фильтр на 20 км работает нормально, как и поиск.