2008-09-17 10 views
0

Ich bin auf der Suche nach einer Variante der #save Methode, die nur Attribute speichert, die keine Fehler enthalten. So kann ein Modell aktualisiert werden, ohne dass es insgesamt gültig ist, und dies verhindert weiterhin, dass ungültige Daten in der Datenbank gespeichert werden .ActiveRecord # save_only_valid_attributes

Mit „gültigen Attributen“, meine ich jene Attribute, die Null geben, wenn @ model_instance.errors.on Aufruf (: Attribut)

Wer eine Vorstellung davon hat, wie dies zu erreichen?

Bisher habe ich folgendes:

def save_valid_attributes 
valid? 
update_atrtibutes attributes.inject({}){|k, v, m| m[k] = v unless errors_on(k.to_sym); m} 
end 

Dies funktioniert, wenn es keine Verarbeitung im Auftrag erledigt ist, was in meinem Fall ist. Zum Beispiel habe ich eine Datenbankspalte „start_date“, und zwei Methoden definiert:

def nice_start_date=(startdate) 
self.start_date = Chronic.parse(startdate) || startdate 
end 

def nice_start_date 
self.start_date.to_s 
end 

Diese beiden Methoden erlauben Sie mir richtig die Benutzerdaten vor dem Speichern Chronic eingegeben zu analysieren verwenden. Also, zweiter Weg, dies zu tun, ein Attribut zu einem Zeitpunkt:

def save_valid_attributes(attrib) 
    valid? 
    attrib.each{|(k,v)| send("${k}=", v); save; reload) 
end 

Das Modell neu geladen werden muss, jedes Mal da, wenn eines der Daten ungültig ist und nicht speichert, wird alle weiteren Attribute verhindern vom Speichern.

Gibt es einen besseren Weg, dies zu tun? Ich bin mir sicher, dass dies kein ungewöhnliches Problem in der Rails-Welt ist, ich kann einfach nichts im Google-Universum des Wissens finden.

Antwort

0

ich bin nicht sicher, wie viel Glück man um mit diesem ohne viel Unordnung haben.

Egal wie DRY und OO und einfach Ihr Framework Dinge macht (was in diesem Fall - viel =) Sie müssen immer noch daran denken, es läuft vor einer moor-Standard-relationalen Datenbank, die atomare Commits als hat Eines davon ist definiertFunktionen. Es wurde von Grund auf entwickelt, um sicherzustellen, dass entweder alle Ihre Änderungen durchgeführt werden oder keine.

Sie werden effektiv über sein, um diese Standardfunktionalität mit etwas Reiten, die + 100% gegen den Strich, wie Schienen gehen wurden arbeiten konzipiert. Dies wird wahrscheinlich (wie bereits gesagt) zu inkonsistenten Daten führen.

Having said that. . . es ist immer möglich. Ich würde entlang der Linien der manuellen Validierung der Attribute schauen, die Ihnen wichtig sind, und dann die eingebaute Methode object.update_attribute_with_validation_skipping.

Viel Glück verwenden!

0

Sie können #save wie folgt überschrieben:

def save 
    errors.each do |attr, msg| 
    send("#{attr}=", send("#{attr}_was")) 
    end 
    super 
end 

Dadurch werden alle Attribute mit Fehlern zurückgesetzt ihren ursprünglichen Wert an.