closure_tree icon indicating copy to clipboard operation
closure_tree copied to clipboard

Is there an efficient way of calling .depth on a list of items?

Open asgeo1 opened this issue 9 years ago • 4 comments

I'm trying to build a drop-down list which shows the hierarchy of my categories. So far I have this:

class Hash
  def flatten_nested; flat_map{|k, v| [k, *v.flatten_nested]} end
end

<%= select_tag :category_id,
      options_for_select(
        Category.hash_tree.flatten_nested.map { |c| ['- ' * c.depth + c.name, c.id] },
        params[:category_id]
      ), { include_blank: true, class: 'category-filter chosen-select', :'data-placeholder' => 'Filter by category' }
%>

It looks "good enough", at least the "- " prefix sort of shows the outline of the hierarchy.

The issue is that calling .depth triggers an additional SQL query per item.

Is there a more efficient way in this library to order the nodes by hierarchy, and to also know what their depth is?

The only other thing I could think of was caching the depth property on the model.

asgeo1 avatar Aug 28 '14 00:08 asgeo1

Try just Category.all.map { |c| ['- ' * c.depth + c.name, c.id] }

yurgon avatar Sep 29 '14 07:09 yurgon

@asgeo1 It seems like what you want is a better hash_tree—like, instead of the stringified name of the node, an actual object that contains more than just the name. That seems pretty useful! I'll think about it.

@yurgon calling .map on a scope will cause a query to be performed for every item, and calling Category.all will load every item in the database into memory. Both are very much not recommended.

mceachen avatar Oct 01 '14 02:10 mceachen

How about select id, parent_id, name, (select max(generations) from division_hierarchies where descendant_id=divisions.id) as depth from divisions

smoyte avatar Jun 09 '16 14:06 smoyte

@hooverlunch this helped me a lot! thanks! 💛

pirminis avatar Sep 07 '16 16:09 pirminis