Ho i seguenti modelli:Inserire un modello con l'associazione has_many
# Foo model
schema "foo" do
field :name, :string
has_many: :bars, App.Bar
end
# App model
schema "bar" do
field :name, :string
belongs_to: foo, App.Foo
end
e questa forma:
# form.html (Foo)
<%= form_for @changeset, @action, fn f -> %>
<%= text_input f, :name, class: "form-control" %>
<%= submit "Submit", class: "btn btn-primary" %>
<% end %>
All'interno di questo modulo, come posso aggiungere campi di testo per popolare il mio nuovo Foo
con Bars
?
Quanto segue non funziona perché bars
non è precaricato:
<%= text_input f, :bars, class: "form-control" %>
Sono sulla strada giusta? In tal caso, come posso pre-caricare Bars
nel modulo?
Update, regolatore:
def new(conn, _params) do
changeset = %Foo{} |> Repo.preload(:bars) |> Foo.changeset
render(conn, "new.html", changeset: changeset)
end
def create(conn, %{"foo" => foo_params}) do
changeset = %Foo{} |> Repo.preload(:bars) |> Foo.changeset(foo_params)
if changeset.valid? do
Repo.insert!(changeset)
conn
|> put_flash(:info, "Foo created successfully.")
|> redirect(to: foo_path(conn, :index))
else
render(conn, "new.html", changeset: changeset)
end
end
Il precarico sembra funzionare, ma ottengo un Argument error
al raggiungimento <%= text_input f, :bars, class: "form-control" %>
:
[error] #PID<0.280.0> running App.Endpoint terminated
Server: 192.168.48.202:4000 (http)
Request: GET/
** (exit) an exception was raised:
** (ArgumentError) argument error
:erlang.bit_size([])
(phoenix_html) lib/phoenix_html/tag.ex:66: anonymous fn/2 in Phoenix.HTML.Tag.tag_attrs/1
(elixir) lib/enum.ex:1261: Enum."-reduce/3-lists^foldl/2-0-"/3
(phoenix_html) lib/phoenix_html/tag.ex:35: Phoenix.HTML.Tag.tag/2
(app) web/templates/foo/form.html.eex:16: anonymous fn/1 in App.FooView.form.html/1
(phoenix_html) lib/phoenix_html/form.ex:181: Phoenix.HTML.Form.form_for/4
(app) web/templates/foo/form.html.eex:1: App.FooView."form.html"/1
(app) web/templates/foo/new.html.eex:3: App.FooView."new.html"/1
Che aspetto ha il controller? Potresti precaricare Bar nei dati Foo con qualcosa come '' 'foo = Foo |> Repo.get (id) |> Repo.preload ([: barre])' '' assumendo che tu stia usando Ecto e questo è per mostrare una singola barra. Quindi usa un ciclo for nel modello per accedere a ogni foo.bar –
L'azione è # new/# create, non #show. Aggiornato la domanda con il preloading del 'Bars'. – Kernael
@Kernael, potresti pubblicare l'errore completo nella tua domanda? –