#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 км работает нормально, как и поиск.