我已经阅读了所有Yii2 Framework文档,但在尝试实现它时会让人感到困惑。
我有一个Customer视图,其中显示了customer表中的所有字段,包括地址表中的address_id
字段。
我想在Yii2 Framework中使用MySQL实现连接查询,但生成的代码如下:
模特中的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',
];
}
}
答案 0 :(得分:2)
您需要在ActiveRecord模型中声明一些关系......
请参阅Working with Relational Data
的官方文档如果您将address_id
存储在customer
表格中,那么您将与每个拥有1个单address
(即一对一关系)的客户联系在一起,这是一个相当糟糕的设计。或者您可以使用junction table。最好将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']);
}
然后,您可以通过定义的关系名称从模型实例Access relational data,例如:
// 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文件中创建样板关系代码。