Ich habe ein Entry
Modell, das viele Tag
s hat. Tag
s werden zu einem Eintrag hinzugefügt, indem Sie sie über ein virtuelles Attribut tag_names
in ein Textfeld in meinem Formular eingeben. Vor der Validierung für das Modell Entry
wird die Zeichenfolge tag_names unter Verwendung von find_or_create_by_name
in tatsächliche Tag
Objekte konvertiert. Das Modell Tag
verfügt außerdem über eine Validierung, um sicherzustellen, dass der Tag-Name einer Regex entspricht, die über die Assoziation ausgeführt wird.ActiveRecord Zuordnung wird vor dem Datensatz in einem Update gespeichert
Mein Einstiegsmodell sieht wie folgt aus:
class Entry < ActiveRecord::Base
has_many :entry_tags
has_many :tags, :through => :entry_tags
before_validation :update_tags
attr_writer :tag_names
private
def update_tags
if @tag_names
self.tags = @tag_names.split(",").uniq.map do |name|
Tag.find_or_create_by_name(name.strip)
end
end
end
end
Wenn ich ein neues Entry
-Objekt erstellen und zuweisen Tags, alles funktioniert einwandfrei - die Tags werden nicht gespeichert, wenn es ein Fehler Validierung ist auf einem der Tag
s, und eine Fehlermeldung wird zurückgegeben. Wenn ich jedoch versuche, ein vorhandenes Entry-Objekt mit einem ungültigen Tag zu aktualisieren, statt eine Nachricht zurückzugeben, löst mein Aufruf self.tags=
(in update_tags
oben) eine Ausnahme mit der Validierungsfehlermeldung aus. Selbst wenn ich find_or_create_by_name
überschreibe, um nur ein neues Objekt zurückzugeben, anstatt create
aufzurufen, bekomme ich das gleiche Ergebnis.
Es scheint mir (und die docs scheinen zu bestätigen), dass die tags=
Anruf tatsächlich meine Tag
Objekte speichert, bevor der Haupt-Datensatz gespeichert wird, wenn die Entry
Objekt bereits vorhanden ist. Gibt es etwas, was ich tun kann, damit das Speichern nicht geschieht, oder um zu verhindern, dass es eine Ausnahme auslöst und nur bewirkt, dass meine Speicherung false zurückgibt?
Würde das nicht einfach an Tags angehängt anstatt überschrieben? Ich denke, ich müsste etwas wie "tags.clear" in meiner 'update_tags' Methode machen? Außerdem habe ich versucht, validates_associated vorher zu verwenden, aber ich war am Ende mit doppelten Fehlermeldungen für Tags. –
hmm, ich würde kein "tags.clear" machen - ich bearbeite meinen Code, um mit dem Entfernen von Tags umzugehen, die der Benutzer gelöscht hat. Sie können glücklicher sein, Ihre eigene benutzerdefinierte Validierungsfunktion für das Tags-Array zu schreiben. Vielleicht lohnt es sich, eine weitere Frage zu diesem Thema zu stellen. – austinfromboston