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

J'ai un code comme celui-ci. Je voudrais l'améliorer pour qu'il utilise une méthode, quelque chose comme create_or_update.méthode create_or_update dans les 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 le name existe dans la base de données, alors il doit mettre à jour cet objet sinon il doit créer un nouvel objet.

Y a-t-il une méthode avec laquelle je peux faire ça?

Répondre

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

Remerciements pour. Comme une note, le nom ne doit pas être passé à nouveau puisqu'il a déjà été initialisé avec un nom. De plus, les crochets de hachage ne sont pas nécessaires ici. –

+0

Et donc les opérations sont séparées, pas dans une transaction. – Green

+0

find_or_intialize_by_method est obsolète à partir de 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 réponse vérifiée ci-dessus fonctionne bien pour Rails 3. Cela dit les méthodes find_or_initialize_by_attribute ont été déconseillés dans Rails 4. Ceci est la nouvelle façon. Voir 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' - il retournera le premier si rien n'est trouvé, donc en fait il ne retournera pas l'enregistrement désiré avec un' nom: name' car le premier pourrait être 'name: differentName' , et vous finirez par mettre à jour l'enregistrement indésirable – Aleks

+0

@Aleks vous avez raison. Aurait dû lire 'find_or_initailize (nom: nom)' –

+0

Merci. Retiré le downwote :) – Aleks

Questions connexes