Elixir - 未定义的函数do_match / 4

时间:2017-08-26 05:39:17

标签: elixir ecto elixir-framework

要重构,我正在尝试将代码从我的路由器移到控制器中。

当我这样做时,我收到了这个错误:

  

==文件lib / api / controllers / product.ex ==上的编译错误   **(CompileError)lib / plug / router.ex:211:未定义函数do_match / 4       (stdlib)lists.erl:1338 :: lists.foreach / 2       (stdlib)erl_eval.erl:670 :: erl_eval.do_apply / 6

控制器

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
...

导致错误的原因是什么?

完整错误:

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

1 个答案:

答案 0 :(得分:1)

您收到do_match错误,因为您的模块使用Plug.Router但未定义任何路由。 do_match中的get / post / etc宏添加了Plug.Router个函数子句。如果没有路由,则不会定义任何导致该错误的函数子句。由于您实际上并不想在模块中定义任何路线,因此您只需删除use Plug.Router

您还错过了import功能的put_resp_content_type/2。添加import Plug.Conn应该可以解决这个问题。