Reputation: 151
I'm getting the following error:
protocol Phoenix.HTML.Safe not implemented for {"Bad Product, LLC"}
from the following code:
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
Template:
<%= select f, :company_id, @companies %>
From researching on SO I've tried to add inspect
:
<%= select f, :company_id, inspect @companies %>
but that throws the following error:
protocol Enumerable not implemented for "[{\"Bad Product, LLC\"}]"
It looks like it is trying to escape it as expected, so I refactored the controller to enumerate the companies:
render(conn, "new.html", changeset: changeset, companies: Accounts.list_companies() |> Enum.map(&{&1.name}))
but it still throws the Enumerable not implemented
error.
Thanks!
Upvotes: 1
Views: 1289
Reputation: 151
Thanks again to @sanjaykumar - they were partially correct and helped lead me in the right direction.
Including the id helped, but loading the entire schema was unnecessary. All of the following solutions work:
render(conn, "new.html", changeset: changeset, companies: Accounts.list_companies() |> Enum.map(&{&1.name, &1.id}))
or
render(conn, "new.html", changeset: changeset, companies: Repo.all(Company) |> Enum.map(&{&1.name, &1.id}))
or, what I'm going with:
companies = Repo.all from c in Company, select: {c.name, c.id}
I have limited experience with Elixir and Phoenix, but I suspect that this 3rd query is better than the other two, which are effectively the same other than Accounts.list_companies()
resulting in another function hitting the call stack. They bring the entire Company into memory (I'm guessing), while I suspect the 3rd query only grabs the fields specified. They both also call Enum.map, so another function call.
Upvotes: 1
Reputation: 41
yes
When we call Repo.all(Company), it will load all columns of table, it also loads metadata.If we have huge amount of data there will be performance issue.
The 3rd query you have used, will return list of columns you required.This will definitely going to save bandwidth.
Upvotes: 1
Reputation: 41
companies = Repo.all from c in Company, select: {c.name}
Here you are only selecting name
And you are trying to access company_id
Try
companies = Repo.all(Company)
Upvotes: 2