2013-05-01 12 views
7

Mi piace molto il metodo first_or_create:First_or_create con aggiornamento alla partita?

# Find the first user named Scarlett or create a new one with a particular last name. 
User.where(:first_name => 'Scarlett').first_or_create(:last_name => 'Johansson') 
# => <User id: 2, first_name: 'Scarlett', last_name: 'Johansson'> 

mi chiedevo come avrei potuto anche avere questo aggiornamento l'utente con il cognome 'Johannson' se non è presente o diverso. Alla ricerca del modo più breve per farlo. Un solo rivestimento simile a quello sopra sarebbe l'ideale.

Un possibile approccio è using first_or_initialize combined with update_attributes. L'unica preoccupazione che ho con questo approccio è che avrebbe eseguito un aggiornamento anche se ci fosse una corrispondenza del 100% sui campi forniti.

risposta

6

first_or_initialize con update_attributes dovrebbe andare bene. Rails è abbastanza intelligente che update_attributes colpisce il database solo se ci sono modifiche da apportare (che dovresti essere in grado di confermare da solo utilizzando la console/i registri).

8

Zaid è MOLTO vicino a correggere.

User.where(first_name: 'Scarlett').first_or_create.update(last_name: 'Johansson') 

Differenze dettagliate qui. (Nota: questo è per Rails 3+ e Rails 4+)

  1. La differenza tra first_or_create vs first_or_initialize è che _initialize utilizza il metodo .new e non salva il record vs .create e auto lo salva.

  2. La differenza tra .update vs .update_attributes, .update_attributes è quello che si usa quando si dispone di un hash di valori, in genere proveniente da un formulario presentare come params. D'altra parte, .update permette di specificare facilmente ogni attributo come mostrato sopra (field_column: value, field_column2: value2), ecc

E proprio come Zaid ha detto, ma si applica a entrambi .update e .update_attributes, rotaie aggiornamenti del database" ... colpisce solo il database se ci sono modifiche da apportare ... "

+0

aggiornamento è un metodo privato. Chiamandolo in questo contesto si ottiene "NoMethodError: metodo privato 'update' chiamato ..." È necessario utilizzare update_attributes se si desidera eseguire tutto in una riga. –

+0

Non sono sicuro di come lo hai codificato, ma non dovresti avere problemi in alcun modo. Attualmente sto usando questo in una visione e di controllo in questo formato: 'Session.where (user_id: @user, legal_case_id: @case) .first_or_create.update (last_active: ora)' aggiornamento è sempre stato un pubblico metodo. (Http://apidock.com/rails/ActiveRecord/Relation/update). Anche se si utilizza .update_attributes, è un alias per .update dopo Rails 3+ (http://apidock.com/rails/ActiveRecord/Persistence/update_attributes). Quindi "quasi" non dovrebbe importare in alcun modo. –