1
votes

how to use phoenix.html to create 3 tiers+ associated nested forms? something like

todo_list has_many todo_items has_many item_comments in one form?

same example as this blog a TodoList, with many TodoItems , but I was trying to accomplish one more relationship with TodoItems has_many ItemComments

TodoList model:

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 model:

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 model:

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

the form for create todo list, but I am not sure how to put the item_comments into this form

<%= 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 %>

for the controller I try to use include empty item_comment by default in the new action, and try to put another inputs_for inside the todo_items/inputs_for in the html form, but nothing works at all

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

whats the proper way to do in this kind of form? and how to handle in controller new and create actions?

I have solved the create form problem in my own way, but will not work at the edit form, can anyone tell me the proper way to do it?

    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
We would appreciate to see what you have tried already and what exactly doesn't work.Quality Catalyst
It may also be useful to see your actual schemas.Justin Wood
The question as stated is far too vague to answer. Vote to close.Onorio Catenacci

1 Answers

3
votes
<%= 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 %>

correct answer