Turn an acts_as_tree structure into a select drop-down.
This is probably the easiest way to turn Rails’ acts_as_tree structure into a select field:
HTML:
<select name="category_id"> <%= expand_tree_into_select_field(Category.top) %> </select>
Ruby helper:
def expand_tree_into_select_field(categories) returning(String.new) do |html| categories.each do |category| html << %{<option value="#{ category.id }">#{ ' ' * category.ancestors.size }#{ category.name }</option>} html << expand_tree_into_select_field(category.children) if category.has_children? end end end
The Category.top method is simply:
def self.top find(:all, :conditions => [ 'parent_id IS NULL' ]) end
Finally, your Category class should implement has_children?:
def has_children? children.size > 0 end
That last bit is, of course, optional. You could easily write category.children.size > 0, but that’s not very object-oriented now, is it?
Enjoy!
Did something similar but with checkboxes the other day. Three things: 1) returning - Cool new tool, Ive been looking for something like this.
2) find(:all, :conditions => [ ‘parent_id IS NULL’ ]) - how about find_all_by_parent_id(NULL) ??
3) option_groups_from_collection_for_select ??
Model.find_all_by_parent_id(nil) works, too. Oddly enough I believe I did use that format elsewhere in the program.
Something like this could definitely be turned into a plugin or generic helper method, especially with a block to determine output.