2015-09-07 8 views
9

Ich habe eine Kategorie Tabelle mit Feldern ID, Name und Parent_id. Die Wurzel Kategorien haben PARENT_ID 0. Nun i die Liste der Kategorien in einem Tropfen zeigen will nach unten und eine Struktur wie folgt aus:Zeige Kategorien/Unterkategorien in der Baumhierarchie in einem Dropdown

Hier ist mein Controller:

def new 
    @category = Category.new 
end 

Und hier ist die Ansicht:

<%= f.label :parent_category %> 
    <% categories = Category.all.map{|x| [x.name] + [x.id]} %> 
    <%= f.select(:parent_id, options_for_select(categories), {}, class: 'form-control') %> 

Bitte um Hilfe.

Antwort

10

das Problem gelöst, indem diese Funktionen in application_helper.rb Zugabe

def subcat_prefix(depth) 
    ("&nbsp;" * 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 

und mit ihnen in meiner Ansicht wie diese

<%= f.select(:parent_id, options_for_select(category_options_array), {}, class: 'form-control') %> 
3

Vorausgesetzt, dass Sie die Kinder einer bestimmten Kategorie ähnlich bekommen:

ein Verfahren für die Kategorien, alle Kinder zu bekommen
has_many :children, :class_name => 'Category', :foreign_key => 'parent_id' 

erstellen und die jeweils durch die Ebene einrücken:

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 << "&nbsp;" * 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 

Dann in Ihrem Ansicht:

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

Ich habe nicht 100% getestet, aber die Bits, die ich vorgeschlagen habe, sollten funktionieren ...