Le differenze tra .build, .create e .create! e quando dovrebbero essere usati?


167

Quindi ho visto persone che usano .builde .create, .create!nei loro controller, sempre più recentemente. Qual è la differenza dal solo usare .newe passare l'oggetto param'd e poi .save? Ci sono pro e contro? L'uso di questi altri metodi offre vantaggi?

Risposte:


234

Ci sono un paio di differenze, ma non sono grandi:

  1. .createè equivalente a .newseguito da .save. È solo più succinto.
  2. .create!equivale a .newseguito da .save!(genera un errore se il salvataggio fallisce). È anche solo un po 'più breve
  3. Penso che .buildsia principalmente un alias per .new. Si lavora in un modo in Rails 3 e un altro modo in Rails <3.x

La parte più importante, tuttavia, è che questi metodi possono essere chiamati attraverso un'associazione ( has_many, ecc.) Per collegare automaticamente i due modelli.


1
Ho selezionato questa come la risposta più corretta a causa della menzione sulla possibilità di collegare i modelli associati con loro - questa è una differenza interessante e importante che penso sull'uso di .new e .save. Il che richiede un po 'di lavoro extra. Grazie.
Tim Knight,

11
Chiarimenti minori su 3 - build fa un po 'più di una semplice novità - imposta anche il collegamento dell'associazione.
Two Bit Gangster,

116
Build è diverso da New. Ma la differenza non è che imposta il collegamento dell'associazione (New lo fa anche per la nuova istanza). La differenza è che Build popola il chiamante con la nuova istanza, ma New no. Quindi, ad esempio: Wall.posts.new ti dà un nuovo post associato al tuo Wall, ma Wall.posts è ancora vuoto dopo questa chiamata. Wall.posts.build ti dà un nuovo post associato al tuo Wall e il tuo Wall.posts ora contiene un post.
Amin Ariana,

3
Non è solo un alias ora, senza funzionalità speciali?
Gabriele Cirulli,

14
In Rails 4, ho appena registrato la console. wall.posts.new e wall.posts.build stanno entrambi popolando l'oggetto muro esattamente nello stesso modo. Significa dopo wall.posts.new, wall.posts non è vuoto come affermato nel commento di Amin.
Bot,

35

Anche se è corretto che createchiama newe quindi savec'è una grande differenza tra le due alternative nei loro valori di ritorno.

Saverestituisce trueo falsedipende dal fatto che l'oggetto sia stato salvato correttamente nel database o meno. Questo può quindi essere usato per il controllo del flusso come nel primo esempio nella domanda sopra.

Createrestituirà il modello indipendentemente dal fatto che l'oggetto sia stato salvato o meno. Ciò ha implicazioni per il codice sopra in quanto il ramo superiore dell'istruzione ifverrà sempre eseguito anche se l'oggetto non supera le convalide e non viene salvato.

Se usi createcon la logica di ramificazione sei a rischio di guasti silenziosi che non è il caso se usi new+ save.

create! non soffre dello stesso problema che solleva ed eccezione se il record non è valido.

L' createalternativa può essere utile nei controller in cui respond_withviene utilizzata per le risposte API (JSON / XML). In questo caso, l'esistenza di errori sull'oggetto causerà la restituzione degli errori nella risposta con uno stato di unprocessable_entity, che è esattamente ciò che si desidera da un'API.

Userei sempre l' opzione new+ saveper html, specialmente se fai affidamento sul valore di ritorno per il controllo del flusso.


6

#create è la versione più breve di nuovo e salva. #creare! genera un'eccezione se la convalida non è stata positiva.


5

Secondo le risposte di cui sopra. Inoltre create, non si può passare falsecome argomento con cui si può fare save. Il passaggio falsecome argomento salterà tutte le convalide delle rotaie

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.