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

Ich habe Code wie folgt. Ich möchte es verbessern, so dass es eine Methode verwendet, etwa create_or_update.create_or_update Methode in Schienen

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) 

Wenn die name in der Datenbank vorhanden ist, dann sollte es das Objekt aktualisiert sonst sollte es ein neues Objekt erstellen.

Gibt es eine Methode, mit der ich das machen kann?

Antwort

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

Danke dafür. Als Anmerkung muss der Name nicht erneut übergeben werden, da er bereits mit einem Namen initialisiert wurde. Auch die Hash-Klammern werden hier nicht benötigt. –

+0

Und so Operationen sind getrennt, nicht in einer Transaktion. – Green

+0

find_or_intialize_by_method ist ab Rails 4 veraltet –

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

Die oben geprüft Antwort funktioniert gut für Rails 3. Das heißt die find_or_initialize_by_attribute Methoden in Rails veraltet wurden 4. Dies ist die neue Art und Weise ist. Siehe 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' - es gibt das erste zurück, wenn nichts gefunden wird, so dass es in der Tat nicht den gewünschten Datensatz mit einem' name: name' zurückgibt, da der erste 'name: andersName' sein könnte , und Sie werden am Ende unerwünschte Satz aktualisieren – Aleks

+0

@Aleks Sie sind richtig. Sollte 'find_or_initailize (name: name)' gelesen haben –

+0

Danke. Das Downwote entfernt :) – Aleks

Verwandte Themen