2017-12-26 1 views
0

In meinem RegistrationController @ Speicher sparen, ich tue das folgende:Wie mehrere verwandte Modelle zur gleichen Zeit

  • Erstellen Sie einen Benutzer (User: hasMany() Punkte, hasOne() Profil, belongsToMany() Rolle)
  • Attach eine Rolle (Rolle: belongsToMany() Benutzer)
  • Profil erstellen (Profil: belongsTo() Benutzer)
  • Anfangsbelegung Punktzahl auf 0 (Punkte: belongsTo() Benutzer)

Ich erkannte, wenn einer dieser Schritte fehlschlägt, zum Beispiel wenn aufgrund der langsamen Konnektivität das Profil irgendwie nicht erstellt wird, wird meine App brechen. Hier ist meine Speichermethode:

public function store(){ 
    $profile = new Profile(); 
    $points = new Points(); 
    $this->validate(request(),[ 
     'name' => 'required', 
     'username' => 'required|unique:users', 
     'email' => 'required|email|unique:users', 
     'password' => 'required|confirmed', 
     'role_id' => 'required|between:1,2' 
    ]); 

    $user = User::create([ 
     'name' => request('name'), 
     'username' => request('username'), 
     'email' => request('email'), 
     'password' => bcrypt(request('password')) 
    ]); 

    $role_student = Role::where('title', 'Student')->first(); 
    $role_parent = Role::where('title', 'Parent')->first(); 
    if(request()->input('role_id') == 1){ 
     $user->roles()->attach($role_student); 
    } else if(request()->input('role_id') == 2){ 
     $user->roles()->attach($role_parent); 
    } 

    $profile->user_id = $user->id; 
    $profile->date_of_birth = Carbon::createFromDate(request('year'),request('month'),request('day')); 
    $profile->institution = request('institution'); 
    $profile->class = request('class'); 
    $profile->division = request('division'); 
    $profile->photo = 'propic/default.png'; 
    $profile->bio = 'I am a Member!'; 
    $profile->social_link = 'http://facebook.com/zuck'; 
    $profile->save(); 
    auth()->login($user); 
    \Mail::to($user)->send(new Welcome($user)); 
    $points->updateOrCreateAndIncrement(0); 
    return redirect()->home(); 
} 

Es ist erwähnenswert, dass alle Daten von einem Registrierungsformular kommen. Wie kann ich all diese Schritte gleichzeitig (oder in einer Anweisung) ausführen, damit die Registrierung perfekt synchronisiert wird, wenn die Anweisung erfolgreich ausgeführt wird. Andernfalls werden keine Daten in der Datenbank gespeichert.

+0

Ich glaube, du bist nach [Transaktionen] (https://laravel.com/docs/5.5/database # Datenbank-Transaktionen)? –

+0

@ Don'tPanic Ich weiß nicht, was unter der Haube passiert, aber wenn ich alle Anweisungen von der store() -Methode auf die 'DB :: transaction'-Schließung verschiebe, werde ich in der sicheren Zone sein? – Eisenheim

Antwort

1

Verwenden Sie Transaktionen.

Vor dem ersten DB-Betrieb, in Ihrem Fall: User :: erstellen, verwenden:

DB::beginTransaction(); 

Von nun an setzen alle Ihre db Operationen in try/catch Klammern und wenn eine Ausnahme auftritt, Verwendung:

DB::rollBack(); 

Und am Ende der Funktion, vor return-Anweisung, setzen diese:

DB::commit(); 

Wenn Sie alle Ihre Operationen an der gleichen Stelle haben können, ist es einfacher, dies zu tun:

DB::transaction(function() { 
    //all your db opertaions 
}, 2); 
+0

Wofür ist das zweite Argument? – Eisenheim

+2

@Eisenheim [Anzahl der Versuche, Standardwert ist 1] (https://laravel.com/api/5.5/Illuminate/Database/ConnectionInterface.html#method_transaction). – Tpojka

Verwandte Themen