Rails update_attributes senza salvare?

C’è un’alternativa agli update_attributes che non salva il record?

Quindi potrei fare qualcosa come:

@car = Car.new(:make => 'GMC') #other processing @car.update_attributes(:model => 'Sierra', :year => "2012", :looks => "Super Sexy, wanna make love to it") #other processing @car.save 

A proposito, so che posso @car.model = 'Sierra' , ma voglio aggiornarli tutti su una riga.

Credo che quello che stai cercando sia assign_attributes .

È fondamentalmente lo stesso di update_attributes ma non salva il record:

 class User < ActiveRecord::Base attr_accessible :name attr_accessible :name, :is_admin, :as => :admin end user = User.new user.assign_attributes({ :name => 'Josh', :is_admin => true }) # Raises an ActiveModel::MassAssignmentSecurity::Error user.assign_attributes({ :name => 'Bob'}) user.name # => "Bob" user.is_admin? # => false user.new_record? # => true 

Puoi usare assign_attributes o attributes= (sono gli stessi)

Metodo di aggiornamento cheat sheet (per Rails 4):

  • update_attributes = assign_attributes + save
  • attributes= = alias di assign_attributes
  • update = alias di update_attributes

Fonte:
https://github.com/rails/rails/blob/master/activerecord/lib/active_record/persistence.rb
https://github.com/rails/rails/blob/master/activerecord/lib/active_record/attribute_assignment.rb

Un altro cheat sheet:
http://www.davidverhasselt.com/set-attributes-in-activerecord/#cheat-sheet

Puoi utilizzare il metodo “attributi”:

 @car.attributes = {:model => 'Sierra', :years => '1990', :looks => 'Sexy'} 

Fonte: http://api.rubyonrails.org/classs/ActiveRecord/Base.html

attributes = (new_attributes, guard_protected_attributes = true) Consente di impostare tutti gli attributi in una volta passando un hash con le chiavi corrispondenti ai nomi degli attributi (che corrisponde nuovamente ai nomi delle colonne).

Se guard_protected_attributes è true (il valore predefinito), gli attributi sensibili possono essere protetti da questa forma di assegnazione di massa utilizzando la macro attr_protected. Oppure puoi in alternativa specificare quali attributi sono accessibili con la macro attr_accessible. Quindi tutti gli attributi non inclusi in questo non potranno essere assegnati in massa.

 class User < ActiveRecord::Base attr_protected :is_admin end user = User.new user.attributes = { :username => 'Phusion', :is_admin => true } user.username # => "Phusion" user.is_admin? # => false user.send(:attributes=, { :username => 'Phusion', :is_admin => true }, false) user.is_admin? # => true 

Per l’assegnazione di massa dei valori a un modello di ActiveRecord senza salvare, utilizzare gli attributes= assign_attributes o attributes= . Questi metodi sono disponibili in Rails 3 e versioni successive. Tuttavia, ci sono piccole differenze e trucchi correlati alla versione di cui essere a conoscenza.

Entrambi i metodi seguono questo utilizzo:

 @user.assign_attributes{ model: "Sierra", year: "2012", looks: "Sexy" } @user.attributes = { model: "Sierra", year: "2012", looks: "Sexy" } 

Nota che nessuno dei due metodi eseguirà validazioni o eseguirà callback; i callback e la convalida avverranno quando viene richiamato il save .

Rails 3

attributes= differisce leggermente da assign_attributes in Rails 3. attributes= controllerà che l’argomento passato ad esso sia un hash e ritorna immediatamente se non lo è; assign_attributes non ha tale controllo hash. Consultare la documentazione dell’API Attribute Attribution ActiveRecord per attributes= .

Il seguente codice non valido fallirà silenziosamente semplicemente ritornando senza impostare gli attributi:

 @user.attributes = [ { model: "Sierra" }, { year: "2012" }, { looks: "Sexy" } ] 

attributes= si comporterà silenziosamente come se i compiti fossero stati fatti con successo, quando in realtà non lo erano.

Questo codice non valido solleverà un’eccezione quando assign_attributes prova a stringificare le chiavi hash dell’array che racchiude:

 @user.assign_attributes([ { model: "Sierra" }, { year: "2012" }, { looks: "Sexy" } ]) 

assign_attributes NoMethodError un’eccezione NoMethodError per stringify_keys , a indicare che il primo argomento non è un hash. L’eccezione di per sé non è molto informativa sulla causa effettiva, ma il fatto che si verifichi un’eccezione è molto importante.

L’unica differenza tra questi casi è il metodo utilizzato per l’assegnazione di massa: attributes= assign_attributes e assign_attributes genera un’eccezione per informare che si è verificato un errore.

Questi esempi possono sembrare inventati, e sono in grado, ma questo tipo di errore può facilmente verificarsi quando si convertono dati da un’API, o anche solo usando una serie di trasformazione dei dati e dimenticandosi di Hash[] i risultati della mappa finale. . Mantieni un po ‘di codice 50 righe sopra e 3 funzioni rimosse dal tuo attributo attributo, e hai una ricetta per il fallimento.

La lezione con Rails 3 è questa: usa sempre assign_attributes invece di attributes= .

Rotaie 4

In Rails 4, attributes= è semplicemente un alias per assign_attributes . Consultare la documentazione dell’API Attribute Attribution ActiveRecord per attributes= .

Con Rails 4, entrambi i metodi possono essere usati in modo intercambiabile. Il mancato passaggio di un hash come primo argomento si tradurrà in un’eccezione molto utile: ArgumentError: When assigning attributes, you must pass a hash as an argument.

Validazioni

Se stai pre-flighting assegnazioni in preparazione per un save , potresti essere interessato a convalidare prima di salvare, pure. Puoi usare il valid? e invalid? metodi per questo. Entrambi restituiscono valori booleani. valid? restituisce true se il modello non salvato supera tutte le convalide o false se non lo fa. invalid? è semplicemente l’inverso di valid?

valid? può essere usato in questo modo:

 @user.assign_attributes{ model: "Sierra", year: "2012", looks: "Sexy" }.valid? 

Questo ti darà la possibilità di gestire qualsiasi problema di validazione prima di chiamare save .