Bei der Ausführung wird nie eine Exception geworfen, als Debug-Ausgabe erhalte ich
12not saved34
Was mach ich falsch? Muss ich eine Einstellung in der config beachten?
Wenn ich findByPk auf eine nicht existierende ID Ausführe wird auch keine Exception geworfen, ich bekomme stattdessen einen Fatal error beim save() Aufruf, da $site NULL ist.
Natürlich könnte ich auch den simpleren Weg gehen und $site auf NULL überprüfen und if(!$site->save()) aufrufen, für komplexere Controller mit mehreren beteiligten Models wäre der try catch Ansatz jedoch einfach geschickter.
eine Exception wird nur geworfen, wenn es einen Fehler beim Ausführen der SQL-Anweisung gab. Das ist aber hier nicht der Fall. save() liefert aber wohl false zurück, also ging offensichtlich bei der Validierung was schief. Mach doch einfach mal sowas:
Falls das nichts ausspuckt, wären beforeValidate() und beforeSave() noch Kanditaten. Falls du eine dieser Methoden überschrieben hast, muss diese true zurückgeben, sonst wird das Model nicht gespeichert.
Den Fall, dass $site===null solltest du in jedem Fall abfangen, da du sonst den erwähnten fatal error bekommst. PHP schmeisst leider nicht in jedem Fall eine Exception.
wie ich schon geschrieben hatte könnte ich auch den simpleren Weg gehen und die Werte einzeln überprüfen, das ist mir klar. Ich wollte das Beispiel aus dem Yii Guide nachvollziehen (Kapitel "Transaktionen mit AR") und schauen wo sich das sinnvoll einsetzten lässt.
So wie du auch geschrieben hast dachte ich auch, dass Exceptions nur bei SQL Fehlern geworfen werden. Warum gibt es dann genau das Beispiel für Transaktionen mit AR? In einem Produktivsystem sollten eigentlich keine SQL Fehler mehr auftreten wenn das System ordentlich getestet ist, fehlerhafte POST values können jedoch immer vorkommen.
Angenommen ich hätte 3 verschiedene Models und würde für alle 3 hintereinander save() aufrufen. Beim letzten klappt das save nicht und ich will nun einen Rollback auslösen. Dann kann ich das nicht so machen wie im Beispiel beschrieben, das hab ich verstanden. Was bringt mir das try catch Konzept dann in diesem Zusammenhang? Ich müsste dann ja im Falle if(!$site->save()) selber eine Exception innerhalb des try Blocks werfen …
Den Rückgabewert einer find*()-Methode solltest du immer prüfen. Es ist kein Fehler, wenn nichts gefunden wird, warum sollte also hier eine Exception ausgelöst werden? find() liefert null, findAll() ein leeres Array bei leerem Suchergebnis zurück.
Bzgl. try/catch-Beispiel:
Gute Frage. Ehrlichgesagt bin ich grad auch nicht ganz sicher, ob das Beispiel im Guide gut gewählt ist. Der Kommentar sagt ja:
// find and save are two steps which may be intervened by another request
// we therefore use a transaction to ensure consistency and integrity
Im Beispielzusammenhang seh ich da auch nicht viel Sinn drin. Was sinnvoll gewesen wäre, wäre die Tabelle/den Datensatz zwischen Abfrage und Speichern zu locken. Aber das ist ja was anderes als ne Transaktion.
Sogesehn würd ich mich hier mal nicht zu sehr an den Beispielen aufhängen. Ich würde eher den Rückgabewert von save() prüfen und bei false ein Rollback durchführen. Allerdings auch nur, wenn mehrere verknüpfte Datensätze gespeichert werden sollen. Bei einem einzelnen Datensatz bringt eine Transaktion m.E. recht wenig.