看这里没有多表创建,更新,删除,我写一个吧,大神不要吐CAO [ 2.0 版本 ]
class Customer extends \yii\db\ActiveRecord
{
public function getOrders()
{
// 客户和订单通过 Order.customer_id -> id 关联建立一对多关系
return $this->hasMany(Order::className(), ['customer_id' => 'id']);
}
}
class Order extends \yii\db\ActiveRecord
{
// 订单和客户通过 Customer.id -> customer_id 关联建立一对一关系
public function getCustomer()
{
return $this->hasOne(Customer::className(), ['id' => 'customer_id']);
}
}
两个ActiveRecord 分别是 Customer、Order表(下面用A表与B表表示,打字累)
A表有一个一对多B表的关系,反之B表对应一个对一关系,
创建时
控制器定义两个
$A = new Customer();
$B = new Order();
if($A->load(\Yii::$app->request->post()) && $B->load(\Yii::$app->request->post()){
$A->save();
$A->link('orders', $B);
}
//这下面要注意下要返回两个对象
return $this->render('create', [
'A' => $A,
'B' => $B,
]);
因为你要显示相应的field字duan,
上面意思定义两个模型实例,分别加载post数据,这里的load当没有指定第一个参数时,他会自动载入$this
也就相当于第一个$A->load(\Yii::$app->request->post());等同于$A->load(\Yii::$app->request->post(),'Customet');去看下base\model的load方法就知道了
这里要注意的是View页面
<?= $form->field($a,'customer_id')->textInput()?>;//这是A表的字duan,
<?= $form->field($B,'id')->textInput()?>;//这是B表的字duan,
这样他才会找到相应的模型
创建结束
更新多模型
$A = Customer::findModel($id);
$B = $A->orders; //这里去看手册,这里当用属性方式返回时是取得成品数组,如果用方法,那得$A->getOrders()->all();因为方法得到的是一个对象,
//上面的代码等同于
$A = Customer::find()->with('orders')->where('id=:id', [':id' => $id])->one();
//这样的话$A->orders == $B;
//之后跟上面创建一样
if($A->load(\Yii::$app->request->post()) && $B->load(\Yii::$app->request->post()){
$A->save();
$B->save();
}
//另一种写法
if($A->load(\Yii::$app->request->post()) && $A->orders->load(\Yii::$app->request->post()){
$A->save();
$A->orders->save();
}
更新结束
删除多表
$A = Customer::findModel($id);
$B = $A->orders;
if($A->delete() && $B->delete(){
//删除两张表的数据
}
好了,结束了,给新手吧。第一次发文章
6把刀
注册时间:2016-02-27
最后登录:2020-11-11
在线时长:61小时30分
最后登录:2020-11-11
在线时长:61小时30分
- 粉丝8
- 金钱610
- 威望80
- 积分2020
共 7 条评论
看了半天还是没看懂,太笨
比如一个文章表,一个是文章的附加表,这个就是这个文章的添加,修改,删除。
loadMultiple 和 validateMultiple
你这个是多记录,并不是多表
http://www.yiiframework.com/doc-2.0/guide-input-multiple-models.html
有文档的,只是中文的没翻?
这个是一个controller使用多个model 的示例吗? 不是一个model中包含多个表吧。
请教:你上面的添加例子是 一条Customer一条Order,请问一条Customer多条Order怎么实现? Order用数组传递??
例如新增 一个Custer多个Order
一对多,一对一其实就是他数据为one或all的区别,就像活动记录的one 与 all
而活动记录里的getOrders与getCustomers相当于是活动记录的一个子方法,当你调用他后,你再用 with,他会再去执行一次这个SQL,把这个数据以数组的方式,增加到先前的SQL得到的数据上。这就拼接起来了两个表的数据。
同理,当你三表四表,都是一样的逻辑。
我表达不出来。不知道我说的你理解了没
有个问题 假如用户 id为1 的订单为空 那么Customer::findModel($id)->orders 也为空,view层该如何处理这种空?
isset这个来判断对象是否为空,怎么处理,看你业务逻辑
楼主好,首先感谢您写出这样的教程。我最近也在为这样的问题烦恼!
按照以前的习惯,我会将多个表的操作封装在一个主model里。这样控制器不需要额外的逻辑判断。
楼主这样写,是不是在某些情况下,会吧逻辑写在控制器里呢?比如说,根据返回值,判断是否向某个表里插入扩展数据!!
恩,可以这样,就是可以重写model 的save方法,那以后在外面控制器里只要$a->save他就会把B也存了。
代码这东西,就是结构的拼装,积木块一样,只要你能想,都能有办法实现。只是好与更好的区别。没有最优,只有更优
@6把刀 呵呵,感觉在控制器里写一写逻辑反倒更容易一些!
看理解了,我更喜欢把控制器看成是路由。他只负责引路,而处理的其实是数据模型该做的事。
比如vue2,ng2前端框架
@6把刀 直接重写save会不会有问题?
@chentao 怎么会有问题,不会有问题的。当然save他本身提供了几个事件给你,你可以添加行为触发事件,就不用重写save了。反正条条大路通罗马
hasMany 为什么返回数组内嵌对象啊?$B->delete()报function delete() on array错了,是什么原因?检查了没有用asArray转换