Phoenix Schema在表单选择中分配抛出Phoenix.HTML.Safe未实现错误

时间:2019-04-15 00:01:38

标签: elixir phoenix-framework

我遇到以下错误:

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错误。

谢谢!

3 个答案:

答案 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,因此又调用了一个函数。