За последние 24 часа нас посетили 10298 программистов и 942 робота. Сейчас ищут 317 программистов ...

Добавить поле другой таблицы в search model

Тема в разделе "Yii", создана пользователем rybak94, 14 дек 2016.

Метки:
  1. rybak94

    rybak94 Новичок

    С нами с:
    28 ноя 2016
    Сообщения:
    5
    Симпатии:
    1
    Добрый день, проблемы с добавление поля поиска по элементам с другой таблицы. То есть
    имеется 2 таблицы offer и advertiser, они связаны как hasOne id=>advertiser_id
    в таблице advertiser есть поле advertiser_name, которое я вывожу в gridview на главной странице offer.
    Как показано на рисунке, в offer_name, id есть поиск, а у advertiser_name нету.
    Искал всевозможные гайди по этому, но ничего не нашёл. Понял, что нужно добавить правило, advertiser_name в rules в таблице OfferSearch, но он его не добавляет. Скорей всего его нужно добавить в andFilterWhere, но там он не видит advertiser_name.
    Попробовал сделать ещё одну связь,
    PHP:
    1.     public function getAdd()
    2.     {
    3.         return $this->hasOne(Advertiser::className(), ['id'=> 'advertiser_id'])->select(['id', 'advertiser_name']);
    4.     }
    Но всё ровно не видит.
    Прикладываю фото
    upload_2016-12-14_13-52-7.png
     
  2. denis01

    denis01 Суперстар
    Команда форума Модератор

    С нами с:
    9 дек 2014
    Сообщения:
    12.236
    Симпатии:
    1.716
    Адрес:
    Молдова, г.Кишинёв
    возможно это то, но в кривой реализации
    PHP:
    1.     /**
    2.      * Creates data provider instance with search query applied
    3.      *
    4.      * @param array $params
    5.      *
    6.      * @return ActiveDataProvider
    7.      */
    8.     public function search($params)
    9.     {
    10.         $query = Timetable::find()->
    11.             select('`zlx_timetable`.*, `zlx_rooms`.`name`, `zlx_users`.`fio`, `zlx_users`.`email`, `zlx_users`.`mobilePhone`')->
    12.                 leftJoin('zlx_rooms', '`zlx_rooms`.`id` = `zlx_timetable`.`roomId`')->
    13.                 leftJoin('zlx_users', '`zlx_users`.`id` = `zlx_timetable`.`userId`');
    14.  
    15.         $dataProvider = new ActiveDataProvider([
    16.             'query' => $query->orderBy(['id'=>SORT_DESC]),
    17.         ]);
    18.  
    19.         $this->load($params);
    20.  
    21.         if (!$this->validate()) {
    22.             // uncomment the following line if you do not want to any records when validation fails
    23.             // $query->where('0=1');
    24.             return $dataProvider;
    25.         }
    26.  
    27.         $query->andFilterWhere([
    28.             //'id' => $this->id,
    29.             'active' => $this->active,
    30.             'status' => $this->status,
    31.             'roomId' => $this->roomId,
    32.             'userId' => $this->userId,
    33.         ]);
    34.  
    35.         $query->andFilterWhere(['=', 'zlx_timetable.id', $this->id]);
    36.         $query->andFilterWhere(['like', 'prePayInfo', $this->prePayInfo]);
    37.         $query->andFilterWhere(['>=', new Expression('DATE(zlx_timetable.startAt)'), $this->startAt ]);
    38.         $query->andFilterWhere(['>=', new Expression('DATE(zlx_timetable.createAt)'), $this->createAt ]);
    39.         $query->andFilterWhere(['like', 'zlx_rooms.name', $this->name ]);
    40.         $query->andFilterWhere(['like', 'zlx_users.email', $this->email ]);
    41.         $query->andFilterWhere(['like', 'zlx_users.fio', $this->fio ]);
    42.         $query->andFilterWhere(['like', 'zlx_users.mobilePhone', $this->mobilePhone ]);
    43.  
    44.         return $dataProvider;
    45.     }
     
  3. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.192
    Симпатии:
    1.654
    Если есть связь, используйте joinWith. Автоматически yii2 join-ы для связанных таблиц не ставит
     
    denis01 нравится это.
  4. rybak94

    rybak94 Новичок

    С нами с:
    28 ноя 2016
    Сообщения:
    5
    Симпатии:
    1
    Спасибо, я понял как делать, вот что получилось)
    Всё работает
    PHP:
    1. class OfferSearch extends Offer
    2. {
    3.  
    4.     public $advertiser;
    5.  
    6.     /**
    7.      * @inheritdoc
    8.      */
    9.     public function rules()
    10.     {
    11.         return [
    12.             [['id', 'advertiser_id'], 'integer'],
    13.             [['offer_name', 'advertiser'], 'safe'],
    14.         ];
    15.     }
    16.  
    17.     /**
    18.      * @inheritdoc
    19.      */
    20.     public function scenarios()
    21.     {
    22.         // bypass scenarios() implementation in the parent class
    23.         return Model::scenarios();
    24.     }
    25.  
    26.     /**
    27.      * Creates data provider instance with search query applied
    28.      *
    29.      * @param array $params
    30.      *
    31.      * @return ActiveDataProvider
    32.      */
    33.  
    34.  
    35.     public function search($params)
    36.     {
    37. //        $query = Offer::find()->joinWith('advertiser')
    38. //            ->where(['like', 'advertiser.advertiser_name', 'lead']);
    39.  
    40.         $query = Offer::find();
    41.  
    42.         $query->joinWith(['advertiser']);
    43. //        // add conditions that should always apply here
    44.  
    45.         $dataProvider = new ActiveDataProvider([
    46.             'query' => $query,
    47.         ]);
    48.  
    49.         $dataProvider->sort->attributes['advertiser']=[
    50.             'asc'=>['advertiser.advertiser_name'=>SORT_ASC],
    51.             'desc' => ['advertiser.advertiser_name' => SORT_DESC],
    52.         ];
    53.  
    54.         $this->load($params);
    55.  
    56.         if (!$this->validate()) {
    57.             // uncomment the following line if you do not want to return any records when validation fails
    58.             // $query->where('0=1');
    59.             return $dataProvider;
    60.         }
    61.  
    62.         // grid filtering conditions
    63.         $query->andFilterWhere([
    64.             'id' => $this->id,
    65.             'advertiser_id' => $this->advertiser_id,
    66.         ]);
    67.  
    68.  
    69.         $query->andFilterWhere
    70.         (['like', 'offer_name', $this->offer_name,])
    71.         ->andFilterWhere(['like', 'advertiser_name', $this->advertiser]);
    72.  
    73.         return $dataProvider;
    74.     }
    75. }
    upload_2016-12-15_10-17-5.png
     
  5. avs123

    avs123 Новичок

    С нами с:
    21 фев 2018
    Сообщения:
    5
    Симпатии:
    1
    Для поиска по полю другой таблицы(не просто отображения) в поисковой модели сначала нужно обьявить поля из этой таблицы и добавить их в валидацию и фильтры.
    Например

    PHP:
    1. class SaleSearch extends Sale
    2. {
    3.     public $fullname;
    4.     public $client_email;
    5.     public $course_title;
    6.     public $course_price;
    7.     public $subscribe_status;
    8.  
    9.     /**
    10.      * @inheritdoc
    11.      */
    12.     public function rules()
    13.     {
    14.         return [
    15.             [['id', 'created_at', 'updated_at'], 'integer'],
    16.             [['sale_status', 'method', 'fullname', 'client_email', 'course_title' , 'course_price', 'subscribe_status'], 'safe'],
    17.         ];
    18.     }
    19.  
    20.     /**
    21.      * @inheritdoc
    22.      */
    23.     public function scenarios()
    24.     {
    25.         // bypass scenarios() implementation in the parent class
    26.         return Model::scenarios();
    27.     }
    28.  
    29.     /**
    30.      * Creates data provider instance with search query applied
    31.      *
    32.      * @param array $params
    33.      *
    34.      * @return ActiveDataProvider
    35.      */
    36.     public function search($params)
    37.     {
    38.         $query = Sale::find()->joinWith(['client', 'course']);
    39.  
    40.         // add conditions that should always apply here
    41.  
    42.         $dataProvider = new ActiveDataProvider([
    43.             'query' => $query->asArray(),
    44.             'pagination' => [
    45.                 'pageSize' => 10,
    46.             ],
    47.         ]);
    48.  
    49.         $this->load($params);
    50.  
    51.         if (!$this->validate()) {
    52.             // uncomment the following line if you do not want to return any records when validation fails
    53.             // $query->where('0=1');
    54.             return $dataProvider;
    55.         }
    56.  
    57.         // grid filtering conditions
    58.         $query->andFilterWhere([
    59.             'id' => $this->id,
    60.             'created_at' => $this->created_at,
    61.             'updated_at' => $this->updated_at,
    62.         ]);
    63.  
    64.         $query->andFilterWhere(['like', 'sale_status', $this->sale_status]);
    65.         $query->andFilterWhere(['like', 'client.email', $this->client_email]);
    66.         $query->andFilterWhere(['like', 'course.title', $this->course_title]);
    67.         $query->andFilterWhere(['like', 'course.price', $this->course_price]);
    68.         $query->andFilterWhere(['like', 'client.subscribed', $this->subscribe_status]);
    69.         $query->andWhere('client.fname LIKE "%' . $this->fullname . '%" ' . 'OR client.lname LIKE "%' . $this->fullname . '%"');
    70.         $query->andFilterWhere(['like', 'sale_status', $this->sale_status]);
    71.  
    72.         return $dataProvider;
    73.     }
    Таким же способом можно создавать вспомагательные поля для удобства поиска(например при работе с timestamp)
    см. пример https://github.com/avs123a/yii2-shop2/blob/master/backend/models/ProductSearch.php