2017-08-26 3 views
0

Pour refactoriser, j'essaye de déplacer le code de mon routeur dans les contrôleurs.Elixir - fonction non définie do_match/4

Je reçois cette erreur quand je fais:

== Compilation error on file lib/api/controllers/product.ex == ** (CompileError) lib/plug/router.ex:211: undefined function do_match/4 (stdlib) lists.erl:1338: :lists.foreach/2 (stdlib) erl_eval.erl:670: :erl_eval.do_apply/6

contrôleur

defmodule Api.Controllers.Product do 
    use Plug.Router 
    import Api.ProductCategory 
    alias Api.ProductCategory, as: ProductCategory 
    import Api.Product 
    import Api.Shop 
    alias Api.Shop, as: Shop 
    alias Api.Product, as: Product 
    import Api.ProductShop 
    alias Api.ProductShop, as: ProductShop 
    import Api.Subcategory 
    alias Api.Subcategory, as: Subcategory 
    import Api.Category 
    alias Api.Category, as: Category 
    import Ecto.Query 
    import Api.Repo 

    def put_product(conn) do 

    errors = {} 
    # IO.inspect(conn.body_params) 
    # IO.inspect(conn.query_params["p_id"]) 

    product = Api.Product |> Api.Repo.get(conn.query_params["p_id"]) 
    shop = Api.Shop |> Api.Repo.get(conn.query_params["s_id"]) 

    params = for key <- ~w(image description), 
     value = conn.body_params[key], into: %{}, 
     do: {key, value} 
     changeset = Api.Product.changeset(product, params) 

    case Api.Repo.update(changeset) do 
     {:ok, product} -> 
     errors = Tuple.append(errors, "Product updated") 
     {:error, changeset} -> 
     errors = Tuple.append(errors, "Product not updated") 
    end 

    pid = conn.query_params["p_id"] 
    sid = conn.query_params["s_id"] 
    price = conn.body_params["price"] 

    product_shop = Api.Repo.get_by(ProductShop, s_id: sid, p_id: pid) 
    IO.inspect(product_shop) 

    changeset2 = Api.ProductShop.changeset(product_shop, %{price: price}) 
    case Api.Repo.update(changeset2) do 
     {:ok, product_shop} -> 
     errors = Tuple.append(errors, "Price updated") 
     {:error, changeset2} -> 
     errors = Tuple.append(errors, "Price not updated") 
    end 

    IO.inspect(errors) 

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

router.ex

defmodule Api.Router do 
    use Plug.Router 
    import Api.ProductCategory 
    alias Api.ProductCategory, as: ProductCategory 
    import Api.Product 
    import Api.Shop 
    alias Api.Shop, as: Shop 
    alias Api.Product, as: Product 
    import Api.ProductShop 
    alias Api.ProductShop, as: ProductShop 
    import Api.Subcategory 
    alias Api.Subcategory, as: Subcategory 
    import Api.Category 
    alias Api.Category, as: Category 
    import Ecto.Query 
    import Api.Controllers.Product 
    alias Api.Controllers.Product, as: ProductController 

    if Mix.env == :dev do 
    use Plug.Debugger 
    end 
    plug :match 
    plug Plug.Parsers, parsers: [:json], 
        pass: ["application/json"], 
        json_decoder: Poison 
    plug :dispatch 

    get "/favicon.ico" do 
    # get_categories(conn) 
    end 

    get "/categories/" do 
    get_categories(conn) 
    end 

    options "/categories/" do 
    get_categories(conn) 
    end 
.... 
    put "/products" do 
    ProductController.put_product(conn) 
    end 
... 

Ce qui est à l'origine de l'erreur?

erreur complète:

Benjamins-MacBook-Pro:api Ben$ iex -S mix 
Erlang/OTP 19 [erts-8.2] [source] [64-bit] [smp:8:8] [async-threads:10] [hipe] [kernel-poll:false] [dtrace] 

Compiling 2 files (.ex) 
warning: the variable "errors" is unsafe as it has been set inside a case/cond/receive/if/&&/||. Please explic 
itly return the variable value instead. For example: 

    case int do 
     1 -> atom = :one 
     2 -> atom = :two 
    end 

should be written as 

    atom = 
     case int do 
     1 -> :one 
     2 -> :two 
     end 

Unsafe variable found at: 
    lib/api/controllers/product.ex:54 

warning: the variable "errors" is unsafe as it has been set inside a case/cond/receive/if/&&/||. Please explic 
itly return the variable value instead. For example: 

    case int do 
     1 -> atom = :one 
     2 -> atom = :two 
    end 

should be written as 

    atom = 
     case int do 
     1 -> :one 
     2 -> :two 
     end 

Unsafe variable found at: 
    lib/api/controllers/product.ex:56 

warning: the variable "errors" is unsafe as it has been set inside a case/cond/receive/if/&&/||. Please explic 
itly return the variable value instead. For example: 

    case int do 
     1 -> atom = :one 
     2 -> atom = :two 
    end 

should be written as 

    atom = 
     case int do 
     1 -> :one 
     2 -> :two 
     end 

Unsafe variable found at: 
    lib/api/controllers/product.ex:59 
    lib/api/controllers/product.ex:59 

warning: the variable "errors" is unsafe as it has been set inside a case/cond/receive/if/&&/||. Please explic 
itly return the variable value instead. For example: 

    case int do 
     1 -> atom = :one 
     2 -> atom = :two 
    end 

should be written as 

    atom = 
     case int do 
     1 -> :one 
     2 -> :two 
     end 

Unsafe variable found at: 
    lib/api/controllers/product.ex:65 

warning: variable "shop" is unused 
    lib/api/controllers/product.ex:30 

warning: variable "product" is unused 
    lib/api/controllers/product.ex:38 

warning: variable "changeset" is unused 
    lib/api/controllers/product.ex:40 

warning: variable "product_shop" is unused 
    lib/api/controllers/product.ex:53 

warning: variable "changeset2" is unused 
    lib/api/controllers/product.ex:55 


== Compilation error on file lib/api/controllers/product.ex == 
** (CompileError) lib/plug/router.ex:211: undefined function do_match/4 
    (stdlib) lists.erl:1338: :lists.foreach/2 
    (stdlib) erl_eval.erl:670: :erl_eval.do_apply/6 
+0

Pouvez-vous poster le message d'erreur complet avec la pile complète? – Dogbert

+0

@Dogbert Je viens de poster l'erreur complète dans le terminal. J'ai l'impression de ne pas avoir le stacktrace complet. – BeniaminoBaggins

+0

Je pense que vous devez retirer 'use Plug.Router' de' Api.Controllers.Product'. Cela corrige-t-il quelque chose ou génère-t-il une erreur différente? – Dogbert

Répondre

1

Vous obtenez l'erreur do_match parce que votre module utilise Plug.Router mais ne définit aucun itinéraire. do_match les clauses de fonction sont ajoutées par les macros get/post/etc dans Plug.Router. En l'absence de routes, aucune clause de fonction n'est jamais définie provoquant cette erreur. Puisque vous ne voulez pas vraiment définir de routes dans le module, vous pouvez simplement supprimer use Plug.Router. Il vous manque également un import pour la fonction put_resp_content_type/2. Ajouter import Plug.Conn devrait résoudre ce problème.