Phoenix / Elixir - 协议可枚举未实现

时间:2017-02-13 15:35:00

标签: elixir phoenix-framework ecto

免责声明:我是Phoenix和Elixir的新手

我正在尝试创建一个非常基本的API,用于查询后端MySQL数据库并获取单个记录,编码为JSON并返回。

我有一个已经存在的MySQL数据库,它是现有Python应用程序的一部分,我想在Phoenix中重构应用程序,但保持数据库不变,让新的Phoenix应用程序连接并查询它。

因此,数据库已存在且我没有创建新模式我为每个表定义了模式并将它们放在我的/ lib目录中。

我正在尝试查询TestResultDetail表并获取给定序列号的最后一条记录。 TestResultDetail表与TestResult表有一个ManyToOne关系,该表包含父记录。

我收到以下错误,但不确定如何解决:

  

GET / api / v2 / opt / last-result / 113325-1002上的Protocol.UndefinedError   protocol Enumerable未针对#Ecto.Query实现

Error Message

申请结构:

enter image description here

以下是发生错误的视图:

defmodule Webservices.OPTView do
  use Webservices.Web, :view

    def render("index.json", %{results: results}) do
      %{
      results: Enum.map(results, &result_json/1)
      }
    end

    def render("last.json", %{results: results}) do
      %{
      results: Enum.each(results, &last_result_json/1)
      }
    end

    def result_json(result) do
      %{
      id: result.id,
      serial: result.serial,
      date_added: result.date_added
      }
    end

    def last_result_json(result) do
      %{
      serial: result.serial,
      station: result.station,
      stage: result.stage,
      operator: result.operator,
      revision: result.sequence_rev
      }
    end

end

这是我的架构:(lib / opt_test_result_detail.ex)

defmodule Webservices.TestResultDetail do
  use Ecto.Schema
  import Ecto.Query

  schema "test_result_detail" do
    field :status_id, :integer
    field :station_id, :integer
    field :stage_id, :integer
    field :operator_id, :integer
    field :failstep, :string
    field :shift, :integer
    field :sequence_rev, :integer
    field :date_added, Ecto.Date
    field :date_timestamp, Ecto.DateTime
    field :date_time, Ecto.Time
    field :stage_order, :integer
    field :serial_number, :string
    field :is_retest, :integer
    field :retest_reason, :string

    has_many :result_id, Webservices.TestResult
  end

  # fetch last recorded test result for a serial
  def last_completed_test(serial) do
    from c in Webservices.TestResultDetail,
      join: t in TestResult, on: t.id == c.result_id,
      select: {t.serial, c.station_id, c.stage_id, c.operator_id, c.sequence_rev},
    where: t.serial == ^serial,
    order_by: [desc: c.id],
    limit: 1
  end

end

我的控制器:

defmodule Webservices.OPTController do
    use Webservices.Web, :controller

    alias Webservices.Router
    import Webservices.Router.Helpers

# this is the main controller

#    def index(conn, %{"serial" => serial}) do
#        import Ecto.Query
#
#        results = Webservices.TestResult
#        |> where([p], p.serial == serial)
#        |> Webservices.Repo.all
#
#        render(conn, "index.json", results: results)
#
#    end


    def last(conn, %{"serial" => serial}) do
        import Ecto.Query

        results = Webservices.TestResultDetail.last_completed_test(serial)

        render(conn, "last.json", results: results)
    end
end

1 个答案:

答案 0 :(得分:1)

您忘记在视图中致电package tests; import java.util.HashMap; import java.util.Map; public class ClassTest { interface A {} interface B extends A {} interface C extends A {} class D implements B {} class E implements C {} public ClassTest() { Map<Class<? extends A>, A> map = new HashMap<>(); A d = new D(); A e = new E(); map.put(B.class,d); map.put(C.class,e); map.put(d.getClass(), d); map.put(e.getClass(), e); System.out.println(B.class.getSimpleName() + ": " + map.get(B.class)); System.out.println(C.class.getSimpleName() + ": " + map.get(C.class)); } public static void main(String[] args) { new ClassTest(); } }

Repo.one/1

然而,稍微重构你的代码会更好

results = Webservices.TestResultDetail.last_completed_test(serial)
          |> Repo.one

我也相信这一点:

def last_completed_test(serial) do
  from c in __MODEL__,
    join: t in assoc(c, :results)
    order_by: [desc: c.id],
    where: t.serial == ^serial
end

应该是

has_many :result_id, Webservices.TestResult