2015-11-03 5 views
3

У меня есть 3 модели: PurchaseOrders, PurchaseOrderItems и Vendors. PurchaseOrders может иметь много связанных с BuyOrderItems каждого из них, и каждый PurchaseOrderItem может иметь с ним один Связанный с Продавцом. Моя дилемма заключается в том, что мне нужно не только показать поставщиков в PurchaseOrder GridView, но и сделать этот столбец, который можно фильтровать и сортировать. Я выяснил запрос MySQL, чтобы получить Продавцов, связанных с PurchaseOrder, но я не могу связать все это вместе с Yii2.Yii2 - Сортировка и фильтрация по одному-многим отношениям в GridView

Запрос:

SELECT pos.id, pos.notes, group_concat(distinct(vend.name) order by vend.name ASC SEPARATOR ', ') as vendorNames 
FROM purchase_orders as pos 
JOIN purchase_order_items as PO_item 
ON pos.id = PO_item.purchase_order_id 
JOIN vendors as vend 
ON PO_item.vendor_id = vend.id group by pos.id 

PurchaseOrder Модель:

class PurchaseOrders extends \yii\db\ActiveRecord 
{ 

    public static function tableName() 
    { 
     return 'intra_purchase_orders'; 
    } 

    public function getPurchaseOrderItems() { 
     return $this->hasMany(PurchaseOrderItems::className(['purchase_order_id' => 'id']); 
    } 
} 

PurchaseOrderItems Модель:

class PurchaseOrderItems extends \yii\db\ActiveRecord 
{ 
    public function getVendor() 
    { 
     return $this->hasOne(Vendors::className(), ['id' => 'vendor_id']); 
    } 
} 

Вендоры Модель:

class Vendors extends \yii\db\ActiveRecord 
{ 
    public function getPurchaseOrderItems() 
    { 
     return $this->hasMany(PurchaseOrderItems::className(), ['vendor_id' => 'id']); 
    } 
} 

Есть ли способ связать BuyOrders с поставщиками, чтобы я мог показать связанных с ним поставщиков, как я делаю в MySQL-запросе?

Редактировать Забыл добавить к первоначальному вопросу, я создал функцию в рамках модели PurchaseOrder в список поставщиков, однако; они не сортируются в GridView таким образом.

public function getVendors() { 
    $vendor_arry = []; 

    foreach ($this->purchaseOrderItems as $key => $item) { 
     array_push($vendor_arry, $item->vendor->name); 
    } 
    sort($vendor_arry); 
    return implode(array_unique($vendor_arry, SORT_STRING), ", "); 
} 
+0

может у пожалуйста, дайте скриншот того, как ваш вид сетки должен выглядеть с данными? –

+0

Что мне нужно опубликовать в GridView, это все поля, относящиеся к PurchaseOrder + конкатенированному полю Продавца (то есть «Макдональдс, Burger King, Taco Bell»). –

ответ

5

С нижеследующими модификациями он должен работать нормально.

PurchaseOrder Модель:

<?php 

class PurchaseOrders extends \yii\db\ActiveRecord 
{ 
    public $vendor_name; //This is the variable that will be used for filtering 

    public function rules() 
    { 
     return [ 
      [['vendor_name'], 'string'] //Specify the variable as string 
     ]; 
    } 

    public static function tableName() 
    { 
     return 'intra_purchase_orders'; 
    } 

    public function getPurchaseOrderItems() { 
     return $this->hasMany(PurchaseOrderItems::className(['purchase_order_id' => 'id']); 
    } 

    public function getVendors() { 
     $vendor_arry = []; 

     foreach ($this->purchaseOrderItems as $key => $item) { 
      array_push($vendor_arry, $item->vendor->name); 
     } 

     sort($vendor_arry); 
     return implode(array_unique($vendor_arry, SORT_STRING), ", "); 
    } 
} 

PurchaseOrderSearch Модель:

<?php 

namespace {your_namespace}; 

use Yii; 
use yii\base\Model; 
use yii\data\ActiveDataProvider; 
use app\models\PurchaseOrder; 

class PurchaseOrderSearch extends PurchaseOrder 
{ 
    public function rules() 
    { 
     return [ 
      [['vendor_name'], 'safe'], 
     ]; 
    } 

    public function scenarios() 
    { 
     return Model::scenarios(); 
    } 

    public function search($params) 
    { 
     $query = PurchaseOrder::find()->joinWith(['purchaseOrderItems.vendor']); 

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

     $dataProvider->sort->attributes['vendor_name'] = [ 
      'asc' => ['vendor.name' => SORT_ASC], 
      'desc' => ['vendor.name' => SORT_DESC], 
     ]; 

     $this->load($params); 

     if (!$this->validate()) { 
      return $dataProvider; 
     } 

     $query->andFilterWhere([ 
      'id' => $this->id 
     ]); 

     $query->andFilterWhere(['like', 'vendor.name', $this->vendor_name]); 

     return $dataProvider; 
    } 
} 

PurchaseOrder Контроллер:

class PurchaseOrderController extends Controller 
{ 
    public function actionIndex() 
    { 
     $searchModel = new PurchaseOrderSearch(); 
     $dataProvider = $searchModel->search(Yii::$app->request->queryParams); 

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

И, наконец, настроить вид сетки,

<?php 

use yii\helpers\Html; 
use app\extended\GridView; 

?> 
<?= GridView::widget([ 
    'dataProvider' => $dataProvider, 
    'columns' => [ 
     [ 
      'header' => 'Vendors', 
      'attribute'=>'vendor_name', 
      'value' => function ($model, $key, $index) { 
       return $model->vendors; 
      }, 
     ] 
    ], 
]); ?> 
<?= $this->render('_search', ['model'=>$searchModel]) ?> 

вид поиска: _search.php

<?php 

use yii\helpers\Html; 
use yii\widgets\ActiveForm; 

?> 

<div class="search-form"> 

    <?php $form = ActiveForm::begin([ 
     'action' => ['index'], 
     'method' => 'get', 
    ]); ?> 

    <?= $form->field($model, 'vendor_name') ?> 

    <div class="form-group actions"> 
     <?= Html::submitButton('Search', ['class' => 'btn btn-primary']) ?> 
    </div> 

    <?php ActiveForm::end(); ?> 

</div> 
+1

Отлично, хорошо сформированный ответ. Большое спасибо за это. JoinWith (['purchaseOrderItems.vendor']) - это то, чего я не видел. Ура! –

Смежные вопросы