2

Hey, Kein Rails noob, aber das hat mich ratlos. Mit hat viele durch Assoziationen in Rails. Wenn ich Weine einer Weinbar über einen Weinlistenverband (oder durch einen Tisch) mit etwas ähnlichem zuweise.has_many durch Wegblasen der Assoziation Metadaten über Massenassoziation

class WineBarController 

    def update 

    @winebar = WineBar.find(params[:id]) 

    @winebar.wines = Wine.find(params[:wine_bar][:wine_ids].split(",")) // Mass assign wines. 

    render (@winebar.update_attributes(params[:wine_bar]) ? :update_success : :update_failure) 

    end 

end 

Dadurch wird jede mit dieser Weinbar verknüpfte Weinlistenzeile gelöscht. Dann findet es alle Weine in wine_ids, von denen wir annehmen, dass es eine durch Komma getrennte Reihe von Weiniden ist. Dann fügt es wieder eine neue Assoziation in die Weinliste ein. Dies wäre zwar teuer, aber in Ordnung, wenn die zerstörten Assoziationszeilen keine Metadaten wie den Preis pro Glas und Flasche für die einzelnen Weinbars enthielten.

Gibt es einen Weg, es nicht alles wegblasen zu lassen, nur einen aufzählbaren Vergleich der Arrays und Einfügen löschen, was auch immer sich ändert. Ich habe das Gefühl, dass Schienen etwas sind und ich vermisse etwas Offensichtliches.

Danke.

Antwort

2

Ihr Problem sieht aus wie es mit Ihrer ersten Anweisung in der Update-Methode ist - Sie erstellen einen neuen Weinbar-Datensatz, anstatt einen vorhandenen Datensatz zu laden und zu aktualisieren. Das ist der Grund, warum, wenn Sie die Aufzeichnung untersuchen, nichts von der Beziehung zeigt. Schienen ist intelligent genug, um nicht jeden Datensatz auf der Liste zu löschen/löschen, also mach dir keine Sorgen darüber.

Wenn Sie die Standard-Schienen-Setup für Ihre Formulare verwenden:

<% form_for @wine_bar do |f| %> 

Dann können Sie Ihre Update wie folgt aufrufen:

class WineBarController 
    def update 
    @winebar = WineBar.find(params[:id]) 
    render (@winebar.update_attributes(params[:wine_bar]) ? :update_success : :update_failure) 
    end 
end 

Sie brauchen nicht explizit Ihr Datensatz aktualisieren mit params[:wine_bar][:wine_ids], denn wenn Sie es mit params[:wine_bar] aktualisierten, wurden die wine_ids als Teil davon enthalten. Ich hoffe das hilft!

UPDATE: Sie erwähnten, dass dies nicht funktioniert, weil die Formulare eingerichtet sind, aber Sie können es leicht beheben. In Ihrem Formular möchten Sie das Eingabefeld von wine_bar[wine_ids] in wine_bar[wine_ids_string] umbenennen. Dann brauchen Sie nur die Accessoren in Ihrem Modell zu erstellen, etwa so:

class WineBar < ActiveRecord::Base 
    def wine_ids_string 
    wines.map(&:id).join(',') 
    end 

    def wine_ids_string= id_string 
    self.wine_ids = id_string.split(/,/) 
    end 
end 

Die erste Methode oben ist das „Getter“ - es dauert die Liste der zugehörigen Wein ids und wandelt sie in einen String, dass die Form kann benutzen. Die nächste Methode ist der "Setter", der eine durch Kommas getrennte Zeichenfolge von IDs akzeptiert und sie in das Array aufteilt, das wine_ids= akzeptiert.

Sie könnten auch in meinem Artikel Dynamic Form Elements in Rails interessiert sein, die beschreibt, wie Schienen Formulareingaben nicht auf die Attribute in der Datenbank Datensatz beschränkt sind. Jedes Paar von Zugriffsmethoden kann verwendet werden.

+0

danke für Ihre Antwort, aber das funktioniert nicht. Das Feld wine_ids ist keine verschachtelte Form. es ist eine Schnur. Meine UI passt nicht gut zu der verschachtelten Formularkonvention. Ich habe mein Beispiel aktualisiert, um ein Update zu sein. Duh. Es ist jedoch noch ein zusätzlicher Schritt erforderlich, um die Wein-IDs abzufragen und sie dann mit der Weinbar in Verbindung zu bringen. –

+0

Hallo Lawrence - Ich habe meine Antwort aktualisiert, lass es mich wissen, wenn es hilft. –

Verwandte Themen