2017-10-24 2 views
0

Ich habe ein verschachteltes Formular, wo die nur 1/5 gelieferten Optionen erforderlich ist. Wenn jedoch ein Benutzer das Formular mit nur einem der verschachtelten Formulare ausfüllt, gibt Ecto den Änderungssatz als ungültig zurück.Entfernen von verschachtelten verschachtelten Formular bei der Verwendung von embeds_many

Ich habe einen scrub_params Stecker zu meinem Controller hinzugefügt, aber es scheint, dass leere verschachtelte Formulare nicht entfernt werden.

plug(:scrub_params, "inventories" when action in [:create]) 

Gibt es eine Möglichkeit in Phoenix zu leeren Formen zu entfernen?


Conn Params params [ "Vorräte"]:

%{"payment_invoice_type" => "mail", 
    "delivery_methods" => 
    %{"0" => %{"cost" => "10.00", "description" => "Del Option 1"}, 
    "1" => %{"cost" => "20.00", "description" => "Del Option 2"}, 
    "2" => %{"cost" => "30.00", "description" => "Del Option 3"}, 
    "3" => %{"cost" => nil, "description" => nil}, # should be discarded 
    "4" => %{"cost" => nil, "description" => nil}}, # should be discarded 
    "payment_method" => "cash", 
} 

Changeset Ergebnisse:

#Ecto.Changeset<action: nil, 
changes: %{payment_invoice_type: "mail, 
    delivery_methods: [#Ecto.Changeset<action: :insert, 
    changes: %{cost: #Decimal<10.00>, description: "Del Option 1"}, errors: [], 
    data: #Book.Store.ShippingMethod<>, valid?: true>, 
    #Ecto.Changeset<action: :insert, 
    changes: %{cost: #Decimal<20.00>, description: "Del Option 2"}, errors: [], 
    data: #Book.Store.ShippingMethod<>, valid?: true>, 
    #Ecto.Changeset<action: :insert, 
    changes: %{cost: #Decimal<30.00>, description: "Del Option 3"}, errors: [], 
    data: #Book.Store.ShippingMethod<>, valid?: true>, 
    #Ecto.Changeset<action: :insert, changes: %{}, 
    errors: [description: {"can't be blank", [validation: :required]}, 
     cost: {"can't be blank", [validation: :required]}], 
    data: #Book.Store.ShippingMethod<>, valid?: false>, 
    #Ecto.Changeset<action: :insert, changes: %{}, 
    errors: [description: {"can't be blank", [validation: :required]}, 
     cost: {"can't be blank", [validation: :required]}], 
    data: #Book.Store.ShippingMethod<>, valid?: false>], 
    payment_method: "cash"}, 
errors: [], 
data: #Book.Store.Inventory<>, valid?: false> 

Geordnetes Schema:

Schema "Vorräte" do Feld: payment_invoice_type ,: Zeichenfolge Feld: PAYMENT_METHOD,: string embeds_many: shipping_options, Book.Store.ShippingOptions Zeitstempel() Ende

Eltern Changeset:

def changeset(%Inventory{} = inventory, attrs) do 
    inventory 
    |> cast(attrs, [:payment_invoice_type, :payment_method]) 
    |> validate_required([:payment_invoice_type, :payment_method]) 
    |> cast_embed(:shipping_methods, required: true) 
end 

Embedded Schema:

@primary_key false 
    embedded_schema do 
    field :description, :string 
    field :cost, :decimal 
    end 

    def changeset(%DeliveryOption{} = delivery_option, attrs) do 
    delivery_option 
    |> cast(attrs, [:description, :cost]) 
    |> validate_required([:description, :cost]) 
    |> validate_length(:description, min: 5, max: 75) 
    end 
+1

'scrub_params' tatsächlich richtig ist, hier zu arbeiten, da diese Felder sind' nil', nicht '„“'. – Dogbert

+0

Sie haben Recht. Ich dachte fälschlicherweise, dass 'scrub_params' leere Params entfernt. –

Antwort

0

Das glaube ich nicht, dass es eine Möglichkeit solche Einträge automatisch in Ecto zu entfernen. Sie können manuell die Einträge ziemlich leicht wie folgt entfernen:

inventories = Map.update!(inventories, "delivery_methods", fn map -> 
    :maps.filter(fn _key, value -> !match?(%{"cost" => nil, "description" => nil}, value), map) 
end) 

Dadurch werden alle delivery_methods Werte entfernen, die sowohl cost und description Satz nil haben.

Alternativ werden die folgenden alle Einträge entfernen, die alle ihre Werte auf Null haben:

inventories = Map.update!(inventories, "delivery_methods", fn map -> 
    map |> Map.values |> Enum.all?(&is_nil/1) 
end) 
+0

Beide Filterformen und sicherstellen, dass X Anzahl der Formulare rendern ist ein echtes Problem mit der Ecto-Bibliothek. –

Verwandte Themen