Yii2在单个事务中保存单个保存调用中的相关记录

Gau*_*gla 22 activerecord transactions yii2

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

User - id, name
UserAddress - id , user_id , city
Run Code Online (Sandbox Code Playgroud)

用户表与UserAdress表有一对多的关系

我想做的是:

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

User u = new User();
u.name = "test";
u.userAddress = new Array(ua);
u.save();
Run Code Online (Sandbox Code Playgroud)

调用save on user应该保存用户和useraddress,user_id也设置为user.id

And*_*sky 30

 // 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();

}
Run Code Online (Sandbox Code Playgroud)

  • '$ user-> save()'之后的@trejder实际上并不新鲜.是的,它对我有用. (2认同)
  • 像这样运行 ```$user-&gt;save();``` 可能会导致问题,因为它可能会因验证而失败。请注意,*save()* **不会在启用验证检查(默认)时引发验证错误的异常**。它只会跳过保存 $user 并继续。我建议调用 ```$user-&gt;save(false);``` 来禁用验证并确保在出现问题时抛出异常。 (2认同)

ISt*_*ger 5

除了之前的答案,我提出的变体在没有预先定义的关系和明确处理验证错误的情况下工作.

Yii::$app->db->transaction(function(){

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

    if( !$user->save() ){
        throw new Exception('Can\'t be saved user model. Errors: '. join(', ', $user->getFirstErrors()));
    }

    $userAddress = new UserAddress();
    $userAddress->city      = 'City';
    $userAddress->user_id   = $user->id;

    if( !$userAddress->save() ){
        throw new Exception('Can\'t be saved user address model. Errors: '. join(', ', $userAddress->getFirstErrors()));
    }

});
Run Code Online (Sandbox Code Playgroud)

此代码严格确保将保存两个记录.如果某个模型无法保存,则会因验证错误而抛出异常.