fadeys.work
fadeys.work

Reputation: 499

Laravel DB::transaction doesnt catch the Exception using model events

I'm fairly new to Laravel and I'm trying to work with the Model events. Consider a model has these events (Notice the manually thrown Exception):

class Doctor extends \Eloquent {

    protected $fillable = ['name', 'summary', 'description', 'image'];

    public static function boot() {
        parent::boot();

        Doctor::deleting(function(Doctor $doctor) {
            $doctor->page()->delete();
        });

        Doctor::created(function(Doctor $doctor) {
            throw new \Exception('hahahah!!!');
            $doctor->page()->create(['title' => $doctor->name, 'slug' => $doctor->name]);
        });
    }

    public function page() {
        return $this->morphOne('Page', 'pageable');
    }
}

The Controller's store method:

public function store() {

        // TODO : Extract Validation to a Service.

        $validator = \Validator::make(
            \Input::only('name'),
            ['name' => 'required']
        );
        if ($validator->fails()) {
            return \Redirect::back()->withErrors($validator)->with(['items' => $this->dataArray]);
        }
        $doctor = \Doctor::create(\Input::all());

        \DB::transaction(function() use($doctor) {
            $doctor->save();
        });

        return \Redirect::route('Emc2.doctors.edit', ['id' => $doctor->id]);
    }

The Problem is, the DB::transaction Doesnt catch that Exception thrown by the Model, and so I cannot rollback the transaction.

Am I doing something wrong??

Any help will be appreciated! Thanks!

Upvotes: 0

Views: 1595

Answers (1)

Jarek Tkaczyk
Jarek Tkaczyk

Reputation: 81157

It works as expected. The problem is that you create new entry before wrapping it in transaction.

 $doctor = \Doctor::create(\Input::all()); // It already saved the doctor

 \DB::transaction(function() use($doctor) {
    $doctor->save(); // here you UPDATE doctor
 });

So use this:

 $doctor = new \Doctor(\Input::all());

 \DB::transaction(function() use($doctor) {
    $doctor->save();
 });

or

 \DB::transaction(function() use (&$doctor) {
    $doctor = \Doctor::create(\Input::all());
 });

Upvotes: 4

Related Questions