【问题标题】:How to define a module in Phoenix that uses the Poison Library如何在 Phoenix 中定义一个使用 Poison 库的模块
【发布时间】:2020-08-30 04:49:49
【问题描述】:

我是 Elixir 和 Phoenix 的新手,所以这个问题可能相当简单。我的 Phoenix 应用程序是一个 API 客户端,我正在尝试创建一个结构来对我将从 REST 端点接收的数据进行建模。我基本上是按照Poison GitHub页面上的小例子来创建我的模块:

defmodule ElixirServer.CurrentlyReprModule do
  @derive [Poison.Encoder]

  defstruct [:id, :time, :summary, :icon, :nearestStormDistance,
    :nearestStormBearing, :precipIntensity, :precipProbability, :temperature,
    :apparentTemperature, :dewPoint, :humidity, :pressure, :windSpeed, :windGust,
    :windBearing, :cloudCover, :uvIndex, :visibility, :ozone]
end

该模块位于lib/elixir_server/ 下(这甚至是此类文件的最佳位置吗?)。

我的问题是当我尝试编译文件时出现此错误:

(CompileError) lib/elixir_server/currently_repr_module.ex:2: module Poison.Encoder is not loaded and could not be found

当我尝试运行 iex -S mix 时,我收到了类似的错误:

(UndefinedFunctionError) function Poison.Encoder.__using__/1 is undefined or private

Poison 包含在 mix.exs 的依赖项中。如何解决此错误?

【问题讨论】:

  • 您是否事先运行了 mix deps.get 来获取依赖项?
  • 是的,我已经运行了 mix deps.get。所有依赖项都是最新的,所以 Poison 就在那里。
  • /_build/dev/lib 下可以看到poison 目录吗?您可以尝试再次删除整个_buildmix deps.get
  • 是的,poison目录在/_build/dev/lib
  • 如果我尝试改用 Jason 库,我会在尝试使用模块的控制器中收到不同的错误:CurrentlyReprModule.__struct__/1 is undefined, cannot expand struct CurrentlyReprModule

标签: elixir phoenix-framework elixir-poison


【解决方案1】:

您的问题可能与您的项目结构或您从哪里调用命令有关。这是一个从 0 到 phoenix 的示例,说明如何获取使用 Jason 进行 json 编码的结构体

mix phx.new poison_demo --no-webpack --no-ecto
Fetch and install dependencies? [Yn] y
cd poison_demo

lib/poison_demo_web/router.ex

defmodule PoisonDemoWeb.Router do
  use PoisonDemoWeb, :router

  pipeline :api do
    plug :accepts, ["json"]
  end

  scope "/api", PoisonDemoWeb do
    pipe_through :api
    get "/repr", ReprController, :show
  end
end

lib/poison_demo_web/controllers/repr_controller.ex

defmodule PoisonDemoWeb.ReprController do
  use PoisonDemoWeb, :controller

  def show(conn, _params) do
    json(conn, %CurrentlyReprModule{})
  end
end

lib/repr/repr.ex

defmodule CurrentlyReprModule do
  @moduledoc false
  
  @derive Jason.Encoder
  defstruct [:id, :time, :summary, :icon, :nearestStormDistance,
    :nearestStormBearing, :precipIntensity, :precipProbability, :temperature,
    :apparentTemperature, :dewPoint, :humidity, :pressure, :windSpeed, :windGust,
    :windBearing, :cloudCover, :uvIndex, :visibility, :ozone]
end
iex -S mix phx.server
curl localhost:4000/api/repr

{"apparentTemperature":null,"cloudCover":null,"dewPoint":null,"humidity":null,"icon":null,"id":null,"nearestStormBearing":null,"nearestStormDistance":null,"ozone":null,"precipIntensity":null,"precipProbability":null,"pressure":null,"summary":null,"temperature":null,"time":null,"uvIndex":null,"visibility":null,"windBearing":null,"windGust":null,"windSpeed":null}

【讨论】:

    【解决方案2】:

    所以事实证明我的问题是我的模块别名。这是我之前的elixir_server.ex 文件:

    def repr_module do
        quote do
          use ElixirServer.CurrentlyReprModule
        end
      end
    
      defmacro __using__(which) when is_atom(which) do
        apply(__MODULE__, which, [])
      end
    

    在我aliased 模块之后:

    def repr_module do
        quote do
          alias ElixirServer.CurrentlyReprModule, as: CurrentlyReprModule
        end
      end
    
      defmacro __using__(which) when is_atom(which) do
        apply(__MODULE__, which, [])
      end
    

    仍然不完全确定为什么这解决了 Poison 错误,但是我们接受这些。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-01-31
      • 2020-05-31
      • 1970-01-01
      • 1970-01-01
      • 2018-11-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多