ruby on rails - submenús - Mostrar categorías/subcategorías en la jerarquía de árboles dentro de un menú desplegable
menu desplegable vertical html (2)
Tengo una tabla de categorías con campos id, name y parent_id. Las categorías de raíz tienen parent_id 0. Ahora quiero mostrar la lista de categorías en un menú desplegable y una estructura como esta:
root_category
first_sub_category
sub_sub_category
another_sub_sub_category
second_sub_category
another_root_category
first_sub_category
second_sub_category
Aquí está mi controlador:
def new
@category = Category.new
end
Y aquí está la vista:
<%= f.label :parent_category %>
<% categories = Category.all.map{|x| [x.name] + [x.id]} %>
<%= f.select(:parent_id, options_for_select(categories), {}, class: ''form-control'') %>
Por favor ayuda.
Suponiendo que puede obtener los niños de una categoría determinada similar a:
has_many :children, :class_name => ''Category'', :foreign_key => ''parent_id''
Cree un método para categorías para obtener todos los elementos secundarios y sangría cada uno por nivel:
def all_children2(level=0)
children_array = []
level +=1
#must use "all" otherwise ActiveRecord returns a relationship, not the array itself
self.children.all.each do |child|
children_array << " " * level + category.name
children_array << child.all_children2(level)
end
#must flatten otherwise we get an array of arrays. Note last action is returned by default
children_array = children_array.flatten
end
Entonces en tu opinión:
<select>
<option></option>
<% root_categories.each do |category| %>
<option><%=category.name%></option>
<% category.all_children2.each do |child| %>
<option><%=child.html_safe%></option>
<% end %>
<% end %>
</select>
No lo he probado al 100%, pero los bits que sugerí deberían funcionar ...
Resuelto el problema agregando estas funciones en application_helper.rb
def subcat_prefix(depth)
(" " * 4 * depth).html_safe
end
def category_options_array(current_id = 0,categories=[], parent_id=0, depth=0)
Category.where(''parent_id = ? AND id != ?'', parent_id, current_id ).order(:id).each do |category|
categories << [subcat_prefix(depth) + category.name, category.id]
category_options_array(current_id,categories, category.id, depth+1)
end
categories
end
y usarlos en mi opinión de esta manera
<%= f.select(:parent_id, options_for_select(category_options_array), {}, class: ''form-control'') %>