2010-06-11 12 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 

Tengo un código como este. Me gustaría mejorarlo para que use un método, algo así como create_or_update.create_or_update method in rails

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) 

Si el name existe en la base de datos, entonces debe actualizar ese objeto de lo contrario, debe crear un nuevo objeto.

¿Existe algún método con el que pueda hacer esto?

Respuesta

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

Gracias por esto. Como nota, el nombre no tiene que volver a pasar porque ya se inicializó con un nombre. Además, los paréntesis no son necesarios aquí. –

+0

Y así las operaciones están separadas, no en una transacción. – Green

+0

find_or_intialize_by_method está obsoleto desde 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 respuesta marcada arriba funciona bien para Rails 3. Dicho esto los métodos find_or_initialize_by_attribute quedaron en desuso en los carriles 4. Esta es la nueva forma. Ver 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' - devolverá el primero si no se encuentra nada, por lo que de hecho no devolverá el registro deseado con un' nombre: nombre' ya que el primero podría ser 'name: differentName' , y terminará actualizando el registro no deseado – Aleks

+0

@ Alek, está en lo correcto. Debería haber leído 'find_or_initailize (name: name)' –

+0

Gracias. Se eliminó el downwote :) – Aleks