如何在Phoenix框架中创建嵌套的input_for表单?

时间:2017-01-15 19:14:18

标签: elixir phoenix-framework

如何使用phoenix.html创建3层+关联的嵌套表单?

之类的东西

todo_list has_many todo_items has_many item_comments以一种形式?

与此blog TodoList相同的示例,包含许多TodoItems ,但我试图与TodoItems has_many ItemComments建立一个更多的关系

TodoList型号:

defmodule MyApp.TodoList do
  use MyApp.Web, :model

  schema "todo_lists" do
    field :title, :string            

    has_many :todo_items, MyApp.TodoItem

    timestamps
  end

  def changeset(model, params \\ :{}) do
    model
    |> cast(params, [:title])
    |> cast_assoc(:todo_items)
  end 
end

TodoItem型号:

defmodule MyApp.TodoItem do
  use MyApp.Web, :model

  schema "todo_items" do
    field :body, :string

    belongs_to :todo_list, MyApp.TodoList
    has_many :item_comments, MyApp.ItemComment
    timestamps
  end

  def changeset(model, params \\ :{}) do
    model
    |> cast(params, [:body])
    |> cast_assoc(:item_comments)
  end
end

ItemComment型号:

defmodule MyApp.ItemComment do
  use MyApp.Web, :model

  schema "item_comments" do
    field :body, :string

    belongs_to :todo_item, MyApp.TodoItem

    timestamps
  end

  def changeset(model, params \\ :{}) do
    model
    |> cast(params, [:body])
  end
end

创建待办事项列表的表单,但我不确定如何将item_comments放入此表单

<%= form_for @changeset, todo_lists_path(@conn, :create), fn f -> %>    
  <%= text_input f, :title %>  
  <%= inputs_for f, :todo_items, fn i -> %> 
    <%= text_input i, :body %> 
  <% end %>   
  <button name="button" type="submit">Create</button> 
<% end %>

对于我尝试使用的控制器默认情况下在新操作中包含空item_comment,并尝试在html表单中将todo_items / inputs_for中的另一个inputs_for放入其中,但没有任何效果

changeset = TodoList.changeset(%TodoList{todo_items: [%MyApp.TodoItem{item_comments: [%MyApp.ItemComment{}]}]})

这种形式的正确方法是什么?以及如何在控制器new中处理并创建动作?

我已经以自己的方式解决了创建表单问题,但是无法在编辑表单中工作,有人能告诉我正确的方法吗?

    changeset = TodoList.changeset(%TodoList{todo_items: [%MyApp.TodoItem{}, %MyApp.TodoItem{}]})

<%= form_for @changeset, todo_lists_path(@conn, :create), fn f -> %>    
  <%= text_input f, :title %>  
  <%= inputs_for f, :todo_items, fn i -> %> 
    <%= text_input i, :body %> 
    <%= inputs_for f, :todo_items, fn j -> %> 
      <%= text_input j, :param, name: "todo_list[todo_items][#{i.index}][item_comments][#{j.index}][body]" %>
    <% end %>  
  <% end %>   
  <button name="button" type="submit">Create</button> 
<% end %>

1 个答案:

答案 0 :(得分:2)

<%= form_for @changeset, todo_lists_path(@conn, :create), fn f -> %>    
  <%= text_input f, :title %>  
  <%= inputs_for f, :todo_items, fn i -> %> 
    <%= text_input i, :body %> 
    <%= inputs_for i, :todo_items, fn j -> %> 
      <%= text_input j, :item_comments %>
    <% end %>  
  <% end %>   
  <button name="button" type="submit">Create</button> 
<% end %>

正确答案