Ker*_*ael 13 elixir phoenix-framework
我有以下型号:
# 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
这个形式:
# form.html (Foo)
<%= form_for @changeset, @action, fn f -> %>
  <%= text_input f, :name, class: "form-control" %>
  <%= submit "Submit", class: "btn btn-primary" %>
<% end %>
这里面的形式,我如何添加文本字段来填充我的新Foo用Bars?
以下不起作用,因为bars没有预加载:
<%= text_input f, :bars, class: "form-control" %>
我是在正确的轨道上吗?如果是这样,我怎么能Bars在表格中预加载?
更新,控制器:
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
预加载似乎有效,但我到达Argument error时 
 得到<%= 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
Dav*_*hta 13
查看Jose关于使用关联和嵌入的帖子,找到使用ToDoLists和ToDoItems的强大示例(特别是标题为"嵌套关联和嵌入"的部分).下面的示例是反映您的Foos和Bars组合的衍生示例.
首先,您正走在正确的轨道上:
has_many: :bars, App.Bar
修改您的表单以反映:
# form.html (Foo)
<%= form_for @changeset, @action, fn f -> %>
  <%= text_input f, :name, class: "form-control" %>
  <%= inputs_for f, :bars, fn i -> %>
    <div class="form-group">
      <%= label i, :name, "Bar ##{i.index + 1}", class: "control-label" %>
      <%= text_input i, :name, class: "form-control" %>
  </div>
<% end %>
  <%= submit "Submit", class: "btn btn-primary" %>
<% end %>
这利用inputs_for/4函数from Phoenix.HTML.Form为你的:bars关联生成字段.在这里,我们按顺序标记了"Bar#1"和"Bar#2",并text_input为每个标记提供了标签.
现在,您必须调整控制器new和create操作以反映包含一些条形图(例如两个条形图):
def new(conn, _params) do
  changeset = %Foo{} |> Foo.changeset(%Foo{bars: [%MyApp.Bar{}, %MyApp.Bar{}]})
  render(conn, "new.html", changeset: changeset)
end
def create(conn, %{"foo" => foo_params}) do
  changeset = %Foo{} |> Foo.changeset(foo_params)
  case Repo.insert(changeset) do
    conn
    |> put_flash(:info, "Foo created successfully.")
    |> redirect(to: foo_path(conn, :index))
  else
    render(conn, "new.html", changeset: changeset)
  end
end
你edit和update行动将需要预装吧:
foo = Repo.get!(Foo, id) |> Repo.preload(:bars)
| 归档时间: | 
 | 
| 查看次数: | 4104 次 | 
| 最近记录: |