我遇到以下错误:
protocol Phoenix.HTML.Safe not implemented for {"Bad Product, LLC"}
来自以下代码:
ReviewController
def new(conn, _params) do # creating a review, the Company is a schema association
changeset = Accounts.change_review(%Review{})
companies = Repo.all from c in Company, select: {c.name}
render(conn, "new.html", changeset: changeset, companies: companies)
end
模板:
<%= select f, :company_id, @companies %>
通过研究SO,我尝试添加inspect
:
<%= select f, :company_id, inspect @companies %>
但是会引发以下错误:
protocol Enumerable not implemented for "[{\"Bad Product, LLC\"}]"
看起来它正试图按预期方式对其进行转义,因此我重构了控制器以枚举公司:
render(conn, "new.html", changeset: changeset, companies: Accounts.list_companies() |> Enum.map(&{&1.name}))
但它仍然会引发Enumerable not implemented
错误。
谢谢!
答案 0 :(得分:2)
companies =公司中c中的Repo.all,选择:{c.name}
这里您只选择姓名
您正在尝试访问company_id
尝试
companies = Repo.all(Company)
答案 1 :(得分:1)
是
当我们调用Repo.all(Company)时,它将加载表的所有列,还加载元数据。如果我们有大量数据,则会出现性能问题。
您使用的第三个查询将返回所需列的列表。这肯定会节省带宽。
答案 2 :(得分:0)
再次感谢@sanjaykumar-它们在某种程度上是正确的,并帮助我朝着正确的方向前进。
包括id很有帮助,但是不需要加载整个架构。以下所有解决方案均有效:
render(conn, "new.html", changeset: changeset, companies: Accounts.list_companies() |> Enum.map(&{&1.name, &1.id}))
或
render(conn, "new.html", changeset: changeset, companies: Repo.all(Company) |> Enum.map(&{&1.name, &1.id}))
或者,我要做什么:
companies = Repo.all from c in Company, select: {c.name, c.id}
我在Elixir和Phoenix方面的经验有限,但是我怀疑这第三个查询要比其他两个查询好,它们实际上与Accounts.list_companies()
相同,导致另一个函数到达了调用堆栈。他们将整个公司带入内存(我猜),而我怀疑第三个查询仅获取指定的字段。他们俩都还调用了Enum.map,因此又调用了一个函数。