Rails 3.1 acts_as_tree - 确定孩子?在FormBuilder对象上

时间:2011-10-07 00:30:23

标签: ruby-on-rails ruby-on-rails-3 ruby-on-rails-3.1

我想弄清楚如何做到这一点。我需要通过acts_as_tree模型(下面的MenuHeader)递归地向下钻取。我有以下型号:

class Menu < ActiveRecord::Base
  has_many :menu_headers
  accepts_nested_attributes_for :menu_headers
end

class MenuHeader < ActiveRecord::Base
  belongs_to :menu
  acts_as_tree :parent_id
  has_many :menu_items
  accepts_nested_attributes_for :menu_items
end

class MenuItem < ActiveRecord::Base
  belongs_to :menu_header
  has_one :price
end

我想以嵌套方式遍历所有menu_headers,以便:

menu-1
  menu_header -1
      menu_item - 1
      menu_item - 2
    menu_header -2
        menu_item - 3
        menu_item - 4
  menu_header -3
      menu_item - 5
    menu_header - 4
      menu_header - 5
          menu_item - 6
          menu_item - 7

和实际表格(见问题###)

<%= form_for(@menu) do |f| %>
  <div class="actions">
    <%= f.text_field :content %><br />
    <%= f.fields_for :menu_headers do |mh| %>
      <%=mh.text_field :name %><br />
      <%= mh.fields_for :menu_items do |mi| %>
        <%= mi.text_field :name %><br />
      <% end %>
  <% ### wtf? - the next section should include the above frag in a partial %>
      <% if fields_for :children? %>
          <%= partial 'children' %>
      <% end %>
    <% end %>
    <%= f.submit %>
  </div>
<% end %>

我应该如何处理上面的wft部分?我需要检查FormBuilder对象上是否有子节点(我认为)。第一次在Rails中做这样的事情。

THX

编辑#1 看起来像这样的东西是它的一部分(但几乎不是整个部分):

<%  if mh.object.children.exists? %>
    <%= render :partial => 'children' %>
<% end %>

编辑#2 所以我得到一个孩子的重复渲染。我已经包括了下面发生的事情

应该是(菜单标题缩进2个空格,菜单项4个空格):

menu 1
  mh 1, parent_id=nil
      mi 1 - fk menu_header 1
  mh 2 - parent_id=nil
      mi2 - fk menu_header_id=2
      mi3 - fk menu_header_id=2
    mh 3 parent_id=2 
        mi 4, menu_header_id=3
    mh 4 parent_id=2 
      mh 5 parent_id=4
        mi 5, menu_header_id=5
      mh 6 parent_id=5

在父母中获取表单值 - 第二个菜单标题#4正在重复

menu 1 - menu[content]
mh 1, parent_id=nil - menu[menu_header_attributes][0][name]
    mi 1 - fk menu_header 1 - menu[menu_headers_attributes][0][menu_items_attributes][0][name]
mh 2 - parent_id=nil - menu[menu_headers_attributes][1][name]
    mi2 - fk menu_header_id=2 - menu[menu_headers_attributes][1][menu_items_attributes][0][name]
    mi3 - fk menu_header_id=2 - menu[menu_headers_attributes][1][menu_items_attributes][1][name]
  mh 3 parent_id=2 - menu[menu_headers_attributes][1][children_attributes][0][name]
      mi 4, menu_header_id=3 - menu[menu_headers_attributes][1][children_attributes][0][menu_items_attributes][0][name]
  mh 4 parent_id=2 menu[menu_headers_attributes][1][children_attributes][1][name]
    mh 5 parent_id=4 menu[menu_headers_attributes][1][children_attributes][1][children_attributes][0][name]
        mi 5, menu_header_id=5 menu[menu_headers_attributes][1][children_attributes][1][children_attributes][0][menu_items_attributes][0][name]
    mh 6 parent_id=5 menu[menu_headers_attributes][1][children_attributes][1][children_attributes][0][children_attributes][0][name]
  mh 4 parent_id=2 menu[menu_headers_attributes][2][name]
    mh 5 parent_id=4 menu[menu_headers_attributes][2][children_attributes][0][name]
        mi 5, menu_header_id=5 menu[menu_headers_attributes][2][children_attributes][0][menu_items_attributes][0][name]
      mh 6 parent_id=5 menu[menu_headers_attributes][2][children_attributes][0][menu_items_attributes][0][name]
    mh 5 parent_id=4 - menu[menu_headers_attributes][3][name]
        mi 5, menu_header_id=5 - menu[menu_headers_attributes][3][menu_items_attributes][0][name]
      mh 6 parent_id=5 menu[menu_headers_attributes][3][children_attributes][0][name]

看看这里发生了什么 - 就像children_attributes有点半危险。基于代码的任何想法是怎么回事?我应该提一下Hooray的更新!

1 个答案:

答案 0 :(得分:1)

哎呀,误读了那个。

我相信<%= mh.object.children %>会给你直接孩子的集合,然后你必须递归地在每个孩子(在你的宿位)上调用<%= mh.object.children %>来获得整棵树。

您可能accepts_nested_attributes_for :children允许您设置它们的属性。

修改 这种方法怎么样:

<%= form_for(@menu) do |f| %>
  <div class="actions">
    <%= f.text_field :content %><br />
    <%= f.fields_for :menu_headers do |mh| %>
      <%= render :partial => 'menu_headers/form', :object => mh %>
    <% end %>
    <%= f.submit %>
  </div>
<% end %>

app/views/menu_headers/_form.html.erb

  <%= form.text_field :name %><br />
  <%= form.fields_for :menu_items do |mi| %>
    <%= mi.text_field :name %><br />
  <% end %>

  <%= form.fields_for :children do |mh| %>
     <%= render :partial => 'form', :object => mh %>
  <% end %>

并添加:

accepts_nested_attributes_for :children到您的MenuHeader型号。