Как реализовать объединение запросов в Yii2 - PullRequest
0 голосов
/ 07 июня 2018

Я прочитал всю документацию по Yii2 Framework, но это сбивает с толку при попытке ее реализовать.

У меня есть представление о клиенте, где отображаются все поля в таблице клиентов, включая поле address_id втаблица адресов.

Я хочу реализовать запрос на соединение с использованием MySQL в Yii2 Framework, но сгенерированный код выглядит следующим образом:

CustomerSearch в моделях:

class CustomerSearch extends Customer{
/**
 * {@inheritdoc}
 */
public function rules()
{
    return [
        [['customer_id', 'store_id', 'address_id', 'active'], 'integer'],
        [['first_name', 'last_name', 'email', 'create_date', 'last_update'], '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 = Customer::find();

    // add conditions that should always apply here

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

    $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([
        'customer_id' => $this->customer_id,
        'store_id' => $this->store_id,
        'address_id' => $this->address_id,
        'active' => $this->active,
        'create_date' => $this->create_date,
        'last_update' => $this->last_update,
    ]);

    $query->andFilterWhere(['like', 'first_name', $this->first_name])
        ->andFilterWhere(['like', 'last_name', $this->last_name])
        ->andFilterWhere(['like', 'email', $this->email]);

    return $dataProvider;
}

Класс клиента:

class Customer extends \yii\db\ActiveRecord{
/**
 * {@inheritdoc}
 */
public static function tableName()
{
    return 'customer';
}

/**
 * {@inheritdoc}
 */
public function rules()
{
    return [
        [['store_id', 'first_name', 'last_name', 'address_id'], 'required'],
        [['store_id', 'address_id', 'active'], 'integer'],
        [['create_date', 'last_update'], 'safe'],
        [['first_name', 'last_name'], 'string', 'max' => 45],
        [['email'], 'string', 'max' => 50],
    ];
}

/**
 * {@inheritdoc}
 */
public function attributeLabels()
{
    return [
        'customer_id' => 'Customer ID',
        'store_id' => 'Store ID',
        'first_name' => 'First Name',
        'last_name' => 'Last Name',
        'email' => 'Email',
        'address_id' => 'Address ID',
        'active' => 'Active',
        'create_date' => 'Create Date',
        'last_update' => 'Last Update',
    ];
}
}

1 Ответ

0 голосов
/ 07 июня 2018

Вам необходимо объявить некоторые отношения в ваших моделях ActiveRecord ...

См. Здесь в официальных документах для Работа с реляционными данными

Если вы хранитеaddress_id в вашей таблице customer, тогда вы будете привязаны к каждому клиенту, имеющему 1 единственный address (то есть отношение один к одному), что является довольно плохим дизайном.Или вы можете использовать соединительную таблицу .Вам лучше хранить customer_id в каждой записи адреса и определять отношение «один ко многим», позволяя каждому клиенту хранить несколько адресов (больше как в реальной жизни, т. Е. Для дома, рабочего адреса и т. Д.).

Например, в вашей модели Customer вы бы определили отношение has-many для адресов клиентов:

use app\models\Address;

class Customer extends \yii\db\ActiveRecord
{

    /**
     * {@inheritdoc}
     */
    public static function tableName()
    {
        return 'customer';
    }

    /**
     * {@inheritdoc}
     */
    public function rules()
    {
        return [
            [['store_id', 'first_name', 'last_name', 'primary_address_id'], 'required'],
            [['store_id', 'primary_address_id', 'active'], 'integer'],
            [['create_date', 'last_update'], 'safe'],
            [['first_name', 'last_name'], 'string', 'max' => 45],
            [['email'], 'string', 'max' => 50],
        ];
    }

    /**
     * {@inheritdoc}
     */
    public function attributeLabels()
    {
        return [
            'customer_id' => 'Customer ID',
            'store_id' => 'Store ID',
            'first_name' => 'First Name',
            'last_name' => 'Last Name',
            'email' => 'Email',
            'primary_address_id' => 'Primary Address ID',
            'active' => 'Active',
            'create_date' => 'Create Date',
            'last_update' => 'Last Update',
        ];
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getAddresses()
    {
        return $this->hasMany(Address::className(), ['customer_id' => 'id']);
    }

}

А в вашей модели Address будет определено обратное отношение has-one.:

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getCustomer()
    {
        return $this->hasOne(Customer::className(), ['id' => 'customer_id']);
    }

Затем вы можете Доступ к реляционным данным из экземпляров модели через определенные имена отношений, например:

// SELECT * FROM `customer` WHERE `id` = 123
$customer = Customer::findOne(123);

// SELECT * FROM `address` WHERE `customer_id` = 123
// $addresses is an array of Address objects
$addresses = $customer->addresses;

Также обратите внимание, если вы задаете правильный первичный/ внешние ключи в вашей схеме, генераторы Gii Model / CRUD автоматически создадут шаблонный код отношений в ваших моделях и файлах CRUD.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...