php - Laravel 4 - db transaction on save while automatically creating other model -


i have 2 models: userpayout , usertransaction usertransaction polymorph , needs know model belongs to. whenever user creates payout, transaction should automatically made. if went wrong in process, both should rolled back.

my actual solution follows:

controller:

$user_payout = new userpayout($input); $user->payouts()->save($user_payout); 

userpayout:

public function save(array $options = array()) {     db::begintransaction();      try{         parent::save($options);          $transaction = new usertransaction(             array(                 'user_id' => $this->user_id,                 'template_id' => $this->template->id,                 'value' => -$this->amount             )         );          $this->transactions()->save($transaction);     }     catch(\exception $e)     {         db::rollback();         throw $e;     }      db::commit();      return $this; } 

usertransaction:

public function save(array $options = array()) {     db::begintransaction();      try{         $user = user::find($this->user_id);         $user->balance = $user->balance + $this->value;          if(!$user->save()) throw new exception('user not saved. check validation rules.');          parent::save($options);     }     catch(\exception $e)     {         db::rollback();         throw $e;     }      db::commit();      return $this; } 

well, solution work if need update payout? trigger save function , (of course) create new transaction. absolutely wrong.

so solution apply on creation of payout?

i thought events creating , created. in case of creating can't tell transaction model whom belongs because payout isn't created yet. on other hand in case of created can't tell if went wrong while saving transaction rollback payout.

so right solution here? appreciated.

so solution apply on creation of payout?

you can determine if payout created or updated checking if id set in save() method:

if ($this->id) {   //update transaction } else {   //create transaction } 

secondly, if @ how eloquent handles transactions, you'll see won't nest. first call begintransaction() in call stack starts db transaction , last call commit() commits transaction, don't need worry nested transactions.

and speaking of events, provide nice separation of concerns , using make code more flexible. it's not correct write:

in case of creating can't tell transaction model whom belongs because payout isn't created yet. on other hand in case of created can't tell if went wrong while saving transaction rollback payout.

the callback called on creating event gets object of known type. won't have id, that's true. can still associate model other models , eloquent set foreign keys correctly. make sure use relation methods associate() directly , not set value of foreign key, ids have not been set yet:

$transaction = new usertransaction($data); $transaction->payout()->associate($payout); $transaction->save(); 

you should have @ db::transaction() wrapper eloquent provides. handles begin/commit/rollback less code required:

db::transaction(function () {   // whatever logic needs executed in transaction }); 

you can read more transactions in laravel here: http://laravel.com/docs/5.1/database#database-transactions


Comments

Popular posts from this blog

dns - How To Use Custom Nameserver On Free Cloudflare? -

python - Pygame screen.blit not working -

c# - Web API response xml language -