Die Unterschiede zwischen .build, .create und .create! und wann sollten sie verwendet werden?

167

Ich habe also Leute gesehen, die .build, .create und .create verwenden! innerhalb ihrer Controller in letzter Zeit immer mehr. Was ist der Unterschied, wenn Sie nur .new verwenden und das param'd-Objekt übergeben und dann .save? Gibt es Vor- und Nachteile? Bietet die Verwendung dieser anderen Methoden Vorteile?

Tim Knight
quelle

Antworten:

233

Es gibt ein paar Unterschiede, aber sie sind nicht groß:

  1. .createist gleichbedeutend mit .newgefolgt von .save. Es ist nur prägnanter.
  2. .create!ist gleichbedeutend mit .newgefolgt von .save!(löst einen Fehler aus, wenn das Speichern fehlschlägt). Es ist auch nur ein bisschen kürzer
  3. Ich denke .buildist meistens ein Alias ​​für .new. Es funktioniert in Rails 3 auf eine Weise und in Rails <3.x auf eine andere Weise

Der wichtigste Teil ist jedoch, dass diese Methoden über eine Zuordnung ( has_manyusw.) aufgerufen werden können, um die beiden Modelle automatisch zu verknüpfen.

Zenazn
quelle
1
Ich habe diese als die richtigste Antwort ausgewählt, da erwähnt wird, dass die zugehörigen Modelle mit ihnen verknüpft werden können - das ist ein interessanter und wichtiger Unterschied, über den ich bei der Verwendung von .new und .save nachdenke. Was ein wenig zusätzliche Arbeit erfordert. Vielen Dank.
Tim Knight
11
Kleinere Klarstellungen zu 3 - Build sind etwas mehr als nur neu - sie stellen auch die Assoziationsverbindung her.
Zwei-Bit-Gangster
116
Build unterscheidet sich von New. Der Unterschied besteht jedoch nicht darin, dass die Zuordnungsverknüpfung festgelegt wird (New tut dies auch für die neue Instanz). Der Unterschied besteht darin, dass Build den Aufrufer mit der neuen Instanz füllt, New jedoch nicht. Beispiel: Wall.posts.new gibt Ihnen einen neuen Beitrag, der Ihrer Wall zugeordnet ist, aber Wall.posts ist nach diesem Aufruf noch leer. Wall.posts.build gibt Ihnen einen neuen Beitrag, der Ihrer Wall zugeordnet ist, und Ihre Wall.posts enthalten jetzt einen Beitrag.
Amin Ariana
3
Ist es jetzt nicht nur ein Alias ​​ohne spezielle Funktionalität?
Gabriele Cirulli
14
In Rails 4 habe ich gerade die Konsole eingecheckt. wall.posts.new und wall.posts.build füllen das Wandobjekt auf genau dieselbe Weise. Bedeutet nach wall.posts.new, wall.posts ist nicht leer, wie in Amins Kommentar behauptet.
Bot
35

Obwohl es richtig ist, dass createAufrufe newund dann savegibt es einen großen Unterschied zwischen den beiden Alternativen in ihren Rückgabewerten.

SaveGibt entweder trueoder falseabhängig davon zurück, ob das Objekt erfolgreich in der Datenbank gespeichert wurde oder nicht. Dies kann dann zur Flusskontrolle gemäß dem ersten Beispiel in der obigen Frage verwendet werden.

Creategibt das Modell zurück, unabhängig davon, ob das Objekt gespeichert wurde oder nicht. Dies hat Auswirkungen auf den obigen Code, da der oberste Zweig der ifAnweisung immer ausgeführt wird, auch wenn das Objekt die Validierung nicht besteht und nicht gespeichert wird.

Wenn Sie createmit Verzweigungslogik arbeiten, besteht das Risiko stiller Fehler, was bei Verwendung von new+ nicht der Fall ist save.

create! leidet nicht unter dem gleichen Problem wie es und Ausnahme, wenn der Datensatz ungültig ist.

Die createAlternative kann in Controllern nützlich sein, in denen respond_withAPI-Antworten (JSON / XML) verwendet werden. In diesem Fall führt das Vorhandensein von Fehlern im Objekt dazu, dass die Fehler in der Antwort mit dem Status "zurückgegeben" werden. Dies unprocessable_entityist genau das, was Sie von einer API erwarten.

Ich würde immer die Option new+ savefür HTML verwenden, insbesondere wenn Sie sich für die Flusskontrolle auf den Rückgabewert verlassen.

nmott
quelle
6

#create ist eine kürzere Version von new and save. #erstellen! löst eine Ausnahme aus, wenn die Validierung nicht positiv war.

rkj
quelle
5

Ich würde die obigen Antworten unterstützen. Außerdem createkann man nicht falseals Argument übergeben, mit dem man etwas anfangen kann save. Wenn Sie falseals Argument übergeben, werden alle Schienenüberprüfungen übersprungen

Vineeth Pradhan
quelle