2015-11-03 257 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'])就是我所缺少的。干杯! –