Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Yii2 save related records in single save call in single transaction

In yii2 how can i save multiple related records into db into single save call and single transaction. I have two tables:

User - id, name
UserAddress - id , user_id , city

User table has one to many relation to UserAdress table

What i want to do is :

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

User u = new User();
u.name = "test";
u.userAddress = new Array(ua);
u.save();

calling save on user should save user and useraddress with user_id set to user.id as well

like image 843
Gaurav Singla Avatar asked Nov 11 '14 02:11

Gaurav Singla


2 Answers

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

}
like image 196
Andrey S. Rabchevsky Avatar answered Oct 21 '22 13:10

Andrey S. Rabchevsky


Additionally to previous answer I propose variant that works without preliminarily defined relations and with explicit handling of validation errors.

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

});

This code strictly ensures that both records will be saved. If one of model can't be saved, will be thrown exception with validation error.

like image 36
IStranger Avatar answered Oct 21 '22 13:10

IStranger