Схема Phoenix назначает бросок Phoenix.HTML.Safe не реализована ошибка в форме выбора - PullRequest
0 голосов
/ 15 апреля 2019

Я получаю следующую ошибку:

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 ]

2 голосов
/ 15 апреля 2019

companies = Repo.all от c в Company, выберите: {c.name}

Здесь вы только выбираете имя

И вы пытаетесь получить доступ к company_id

Попробуйте

companies = Repo.all (Компания)

1 голос
/ 15 апреля 2019

да

Когда мы вызываем Repo.all (Company), он загружает все столбцы таблицы, он также загружает метаданные. Если у нас будет огромное количество данных, возникнет проблема производительности.

Третий запрос, который вы использовали, вернет список необходимых вам столбцов. Это определенно сэкономит пропускную способность.

0 голосов
/ 15 апреля 2019

Еще раз спасибо @sanjaykumar - они были частично верны и помогли мне вести в правильном направлении.

Включение идентификатора помогло, но загрузка всей схемы была ненужной.Все следующие решения работают:

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, но я подозреваю, что этот 3-й запрос лучше, чем два других, которые фактически одинаковы, кроме Accounts.list_companies(), в результате чего другая функция попадает в стек вызовов.Они приносят всю компанию в память (я предполагаю), хотя я подозреваю, что третий запрос только захватывает указанные поля.Они оба также вызывают Enum.map, поэтому вызов другой функции.

...