2015-11-03 95 views
3

我有3個模型:PurchaseOrders,PurchaseOrderItems和Vendors。 PurchaseOrders可以有許多PurchaseOrderItems綁定到每個PurchaseOrderItem,並且每個PurchaseOrderItem可以有一個與之關聯的Vendor。我的困境是,我不僅需要在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']); 
    } 
} 

有沒有辦法將PurchaseOrders與供應商聯繫起來,這樣我就可以顯示與它相關的供應商,就像我在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 +連鎖供應商字段(即「McDonalds,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'])就是我所缺少的。乾杯! –