Activerecord Yii2在单笔交易的单次保存调用中保存相关记录

Activerecord Yii2在单笔交易的单次保存调用中保存相关记录,activerecord,transactions,yii2,Activerecord,Transactions,Yii2,在yii2中,如何将多个相关记录保存到数据库中,并保存到单个保存调用和单个事务中。 我有两张桌子: User - id, name UserAddress - id , user_id , city 用户表与UserAddress表具有一对多关系 我想做的是: UserAddress ua = new UserAddress(); ua.city = "fff" User u = new User(); u.name = "test"; u.userAddress = new Array(u

在yii2中,如何将多个相关记录保存到数据库中,并保存到单个保存调用和单个事务中。 我有两张桌子:

User - id, name
UserAddress - id , user_id , city
用户表与UserAddress表具有一对多关系

我想做的是:

UserAddress ua = new UserAddress();
ua.city = "fff"

User u = new User();
u.name = "test";
u.userAddress = new Array(ua);
u.save();
在user上调用save应该保存user和useraddress,并将user_id设置为user.id

//您需要创建多个关系“useraddress”(look-guide-relations)
 // You need create hasMany relation 'userAddress' (look guide relations)

$transaction = Yii::$app->db->beginTransaction();

try {

    $user = new User();
    $user->name = 'Name';
    $user->save();

    $ua = new UserAddress();
    $ua->city = 'City';

    $user->link('userAddress', $ua); // <-- it creates new record in UserAddress table with ua.user_id = user.id

    $transaction->commit();

} catch (Exception $e) {

    $transaction->rollBack();

}
$transaction=Yii::$app->db->beginTransaction(); 试一试{ $user=新用户(); $user->name='name'; $user->save(); $ua=新用户地址(); $ua->city='city'; $user->link('userAddress',$ua);//提交(); }捕获(例外$e){ $transaction->rollBack(); }
除了前面的答案之外,我还提出了一种变体,它可以在没有初步定义关系的情况下工作,并且可以显式处理验证错误

Yii::$app->db->transaction(函数(){
$user=新用户();
$user->name='name';
如果(!$user->save()){
抛出新异常('无法保存用户模型。错误:'.join(',',$user->getFirstErrors());
}
$userAddress=新的userAddress();
$userAddress->city='city';
$userAddress->user\u id=$user->id;
如果(!$userAddress->save()){
抛出新异常('无法保存用户地址模型。错误:'.join(',',$userAddress->getFirstErrors());
}
});

此代码严格确保两条记录都将被保存。如果其中一个模型无法保存,将抛出异常并出现验证错误。

两个插入是否都在单个文件中?您在示例中对两个新创建的活动记录使用了该方法。然而,在Yi2文档中的“”文章中有一条信息:“注意:您不能链接两个新创建的活动记录实例”,该示例仅显示将新子模型链接到现有主模型。看起来,您的解决方案不起作用,或者Yii2文档中有一个bug。你测试过你的答案吗?@trejder在“$user->save()”之后,实际上它不是新的。是的,它适合我。运行
$user->save()这样会在这里引起问题,因为它可能会由于验证而失败。注意,启用验证检查(默认)时,save()不会引发验证错误异常。它将跳过保存$user并继续。我建议调用
$user->save(false),以禁用验证并确保在出现错误时引发异常。@user1132363我同意您的看法。我在下面添加了处理验证错误的变体。