2017-07-09 5 views
0

Comment ajouter un champ à un changeset uniquement si le champ n'est pas nul? Je ne veux pas mettre à jour la valeur dans la base de données si la valeur est nulle. Je dois vérifier 3 champs et seulement mettre à jour ceux qui ne sont pas nuls.Ecto changeset - ignorer les champs

code actuel:

put "/products" do 
    errors = {} 
    IO.inspect(conn.body_params) 

    product = Api.Product |> Api.Repo.get(conn.query_params["id"]) 
    IO.inspect(product) 

    if conn.body_params["image"] do 
     changeset = Api.Product.changeset(product, %{image: conn.body_params["image"]}) 
    end 

    if conn.body_params["description"] do 
     changeset = Api.Product.changeset(product, %{description: conn.body_params["description"]}) 
    end 

    if conn.body_params["price"] do 
     changeset = Api.Product.changeset(product, %{price: conn.body_params["price"]}) 
    end 
    case Api.Repo.update(changeset) do 
     {:ok, product} -> 
     errors = Tuple.append(errors, "Product updated") 
     {:error, changeset} -> 
     errors = Tuple.append(errors, "Product not updated") 
    end 

    conn 
     |> put_resp_content_type("application/json") 
     |> send_resp(200, Poison.encode!(%{ 
      successs: "success", 
      errors: Tuple.to_list(errors) 
     })) 
    end 

Répondre

1

Vous pouvez créer une nouvelle params carte avec uniquement les touches dont le schéma accepte et dont la valeur est non nulle à l'aide for et passer que pour changeset/2:

product = Api.Product |> Api.Repo.get(conn.query_params["id"]) 
params = for key <- ~w(image description price), value = conn.body_params[key], into: %{}, do: {key, value} 
changeset = Api.Product.changeset(product, params) 
case Api.Repo.update(changeset) do 
    ... 
end 
0

C'est ce que validate_required/3 est pour. Vous lui transmettez votre changeset et une liste de champs obligatoires en tant qu'atomes. Si l'un des champs spécifiés n'est pas présent (par exemple, nil), une erreur sera ajoutée à votre ensemble de modifications et elle sera également marquée comme non valide.

iex> changeset |> validate_required([:field1, :field2, :field3]) 
%Ecto.Changeset{valid?: false, errors: %{"field1" => ["can't be blank"]}} 

PS. vous n'avez pas besoin de gérer vous-même les erreurs comme vous le faites ci-dessus. Les erreurs seront automatiquement ajoutées à votre ensemble de modifications au changeset.errors.

+0

Je leur ai besoin de pouvoir être nul au cours une insertion. Ensuite, je n'ai besoin de les mettre à jour ici que s'ils ont des valeurs au lieu de zéro. Je dois m'assurer qu'il ne provoque pas d'erreur si l'un d'eux est nul car les autres qui ne sont pas nuls doivent être sauvegardés. – BeniaminoBaggins