如何从相关表中获取和搜索属性,通过另一个相关表 - 一对一关系

时间:2017-08-13 08:35:18

标签: yii2

我有三张表如下:

政策:(id,r_available_taemin [fk]) -

available_taemin :( id ,, name,r_company [fk]) -

公司:(id,name)

在策略(索引)的网格视图中,我需要显示公司名称,我已经这样做了。 但现在我需要为公司名称添加过滤,在这里我遇到了问题。

我的搜索模型如下:

<?php

namespace app\models;

use Yii;
use yii\base\Model;
use yii\data\ActiveDataProvider;
use app\models\appmodels\AppPoliciesGeneral;

/**
 * PoliciesGeneralSearch represents the model behind the search form of `app\models\appmodels\AppPoliciesGeneral`.
 */
class PoliciesGeneralSearch extends AppPoliciesGeneral {

    public $customerName;
    public $companyName;

    /**
     * @inheritdoc
     */
    public function rules() {
        return [
            [['policy_id', 'r_deal_type', 'r_customer_id', 'r_available_taemin', 'is_active', 'r_invoice', 'isRenewed'], 'integer'],
            [['policy_type', 'policy_code', 'madmoun_name', 'payment_option', 'contract_date', 'start_date', 'end_date', 'attachment', 'sale_letters', 'paid_customer_letters', 'paid_company_letters', 'table_name', 'deactivated_at', 'created_at', 'updated_at'], 'safe'],
            [['cost', 'price', 'sale', 'tax', 'paid_customer', 'remaining_customer', 'paid_company', 'remaining_company'], 'number'],
            [['customerName', 'companyName'], 'safe'],
        ];
    }

    /**
     * @inheritdoc
     */
    public function scenarios() {
        // bypass scenarios() implementation in the parent class
        return Model::scenarios();
    }

    /**
     * Creates data provider instance with search query applied
     *
     * @param array $params
     *
     * @return ActiveDataProvider
     */
    public function search($params) {
        $query = AppPoliciesGeneral::find();

        // add conditions that should always apply here
        $dataProvider = new ActiveDataProvider([
            'query' => $query,
        ]);
        $dataProvider->setSort([
            'attributes' => [

        $query->joinWith(['rCustomer']);
        $query->joinWith(['rAvailableTaemin']);
//        $query->joinWith(['rCompany']);

                $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([
        'policy_id' => $this->policy_id,
                'r_deal_type' => $this->r_deal_type,
                'r_customer_id' => $this->r_customer_id,
                'r_available_taemin' => $this->r_available_taemin,
                'contract_date' => $this->contract_date,
                'start_date' => $this->start_date,
                'end_date' => $this->end_date,
                'is_active' => $this->is_active,
                'cost' => $this->cost,
                'price' => $this->price,
                'sale' => $this->sale,
                'tax' => $this->tax,
                'paid_customer' => $this->paid_customer,
                'remaining_customer' => $this->remaining_customer,
                'paid_company' => $this->paid_company,
                'remaining_company' => $this->remaining_company,
                'r_invoice' => $this->r_invoice,
                'deactivated_at' => $this->deactivated_at,
                'isRenewed' => $this->isRenewed,
                'created_at' => $this->created_at,
                'updated_at' => $this->updated_at,
                ]);

                $query->andFilterWhere([ 'like', 'policy_type', $this->policy_type])
                        ->andFilterWhere([ 'like', 'policy_code', $this->policy_code])->andFilterWhere(['like', 'madmoun_name', $this->madmoun_name])->andFilterWhere(['like', 'payment_option', $this->payment_option])->andFilterWhere(['like', 'attachment', $this->attachment])->andFilterWhere(['like', 'sale_letters', $this->sale_letters])->andFilterWhere(['like', 'paid_customer_letters', $this->paid_customer_letters])->andFilterWhere(['like', 'paid_company_letters', $this->paid_company_letters])->andFilterWhere(['like', 'table_name', $this->table_name]);

        $query->joinWith(['rCustomer' => function ($q) {
            $q->where('customers.first_name LIKE "%' . $this->customerName . '%"' .
                    'OR customers.fathers_name LIKE "%' . $this->customerName . '%"' .
                    'OR customers.last_name LIKE "%' . $this->customerName .  '%"'
            );
        }]);

//        $query->joinWith(['rAvailableTaemin' => function ($q) {
//                $q->where('companies.reprisentative_name LIKE "%' . $this->companyName . '%"');
//            }]);
//        $query->joinWith(['rCompany' => function ($q) {
                //                $q->where('companies.name LIKE "%' . $this->companyName . '%"');
//            }]);
//        $query->joinWith(['companies' => function ($q) {
//                $q->where('companies.name LIKE "%' . $this->companyName . '%"');
//            }]);

                return $dataProvider;
                }

                }

我的模特到现在如下:

<?php

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

namespace app\models\appmodels;

use app\models\PoliciesGeneral;
use Yii;

/**
 * Description of AppPoliciesGeneral
 *
 * @author BigUser
 */
class AppPoliciesGeneral extends PoliciesGeneral {

    public function getRCustomer() {
        return $this->hasOne(AppCustomers::className(), ['id' => 'r_customer_id']);
    }

    public function getCustomerName() {
//        return $this->rCustomer->first_name . " " . $this->rCustomer->fathers_name . " " . $this->rCustomer->last_name . "";
        return $this->rCustomer->fullName;
    }

    public function getRAvailableTaemin() {
        return $this->hasOne(AppAvailableTaemin::className(), ['id' => 'r_available_taemin']);
    }

//public function getRCompany() {
//        return $this->hasMany(AppCompanies::className(), ['r_company' => 'id'])
//                        ->viaTable('available_taemin', ['r_available_taemin' => 'id']);
//    }

    public function getCompanyid() {
        return $this->rAvailableTaemin->r_company;
    }

    public function getRCompany() {
        return $this->hasOne(AppCompanies::className(), ['id' => 'companyid']);
    }

    public function getCompanyName() {
        return $this->rCompany->name;
    }

//    public function getCompanyName() {
//        return $this->rAvailableTaemin->companyName;
//    }


}

感谢先生。

1 个答案:

答案 0 :(得分:1)

我不知道这里有什么问题。看看你的代码,我可以看到公司名称的过滤,但它被注释掉了,为什么?

无论如何,提示很少:

您不必为排序设置所有属性,它会自动完成,只是不要像在此处一样覆盖它。由于您有两个虚拟属性,请执行以下操作:

$dataProvider->sort->attributes['companyName'] = [
    'asc' => ['companies.name' => SORT_ASC],
    'desc' => ['companies.name' => SORT_DESC],
    'label' => 'Company Name',
    'default' => SORT_ASC
];
$dataProvider->sort->attributes['customerName' = [
    'asc' => ['customers.first_name' => SORT_ASC, 'customers.fathers_name' => SORT_ASC, 'customers.last_name' => SORT_ASC],
    'desc' => ['customers.first_name' => SORT_DESC, 'customers.fathers_name' => SORT_DESC, 'customers.last_name' => SORT_DESC],
    'label' => Yii::t('app', 'Customer Name'),
];

这就是全部。其余属性将被添加为自动排序。

客户过滤 - 已经增加了关系,您不必再次这样做。

if (!empty($this->customerName)) {
    $query->andWhere([
        'or',
        ['like', 'customers.first_name', $this->customerName],
        ['like', 'customers.fathers_name', $this->customerName],
        ['like', 'customers.last_name', $this->customerName],
    ]);
}

现在公司过滤,这更容易,因为您只检查一列:

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