2010-06-11 11 views
23
if ClassName.exists?(["id = ?", self.id]) 
    object = ClassName.find_by_name(self.name) 
    object.update_attributes!(:street_address => self.street_address, 
    :city_name => self.city_name, 
    :name => self.org_unit_name, 
    :state_prov_id => self.state_prov_id, 
    :zip_code => self.zip_code) 
else 
    ClassName.create! :street_address => self.street_address, 
    :city_name => self.city_name, 
    :federalid => self.federalid, 
    :name => self.org_unit_name, 
    :state_prov_id => self.state_prov_id, 
    :zip_code => self.zip_code 
end 

Ho codice come questo. Mi piacerebbe migliorarlo in modo che usi un metodo, qualcosa come create_or_update.metodo create_or_update in rotaie

ClassName.create_or_update_by_name(:name => self.name, 
    :street_address => self.street_address, 
    :city_name => self.city_name, 
    :federalid => self.federalid, 
    :name => self.org_unit_name, 
    :state_prov_id => self.state_prov_id, 
    :zip_code => self.zip_code) 

Se il name esiste nel database allora dovrebbe aggiornare l'oggetto altrimenti si dovrebbe creare un nuovo oggetto.

Esiste un metodo con cui posso farlo?

risposta

79
my_class = ClassName.find_or_initialize_by_name(name) 

my_class.update_attributes(
    :street_address => self.street_address, 
    :city_name => self.city_name, 
    :federalid => self.federalid, 
    :state_prov_id => self.state_prov_id, 
    :zip_code => self.zip_code 
) 
+3

Grazie per questo. Come nota, il nome non deve essere passato di nuovo poiché era già inizializzato con un nome. Anche qui le staffe hash non sono necessarie. –

+0

E quindi le operazioni sono separate, non in una transazione. – Green

+0

find_or_intialize_by_method è obsoleto a partire da Rails 4 –

6
person = Person.find_by_name(name) || Person.new(:name => name) 
person.update_attributes!(:street_address => street_address, :city_name => city_name) #etc etc 
8

La risposta controllato sopra funziona bene per Rails 3. che dicono che i metodi find_or_initialize_by_attribute sono stati deprecati in Rails 4. Questo è il nuovo modo. Vedi Rails4 Deprecation warning for find_or_initialize_by method

person = Person.find_or_initialize(name: 'name') 
person.update_attributes(other_attrs) 
+0

'First_or_initialize' - restituirà il primo se non viene trovato nulla, quindi in effetti non restituirà il record desiderato con un' nome: nome' come il primo potrebbe essere 'nome: differentName' , e finirai per aggiornare il record indesiderato – Aleks

+0

@Aleks hai ragione. Dovrebbe aver letto 'find_or_initailize (nome: nome)' –

+0

Grazie. Rimosso il downwote :) – Aleks