免责声明:我是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实现
申请结构:
以下是发生错误的视图:
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
答案 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