From time to time you get to a point where you want to structure your data in a tree like format. That means you usually want to have some kind of root node that has children and those children could optionally have other children and so on and so forth.
That is what is referred to as the nested set model and depending on preference you might have a left and right field for determining the position of the element in the tree and you could also have a depth field for better performance.
In any case, in Ruby on Rails it’s very easy to use nested sets with the many gems already available like for example (the one I go to every time) awesome_nested_set.
With this gem you only need to include a line in your model and you’re all set.
# Gemfile
gem 'awesome_nested_set'
# config/routes.rb
class CreateCategories < ActiveRecord::Migration
def self.up
create_table :categories do |t|
t.string :name
t.integer :parent_id, :null => true, :index => true
t.integer :lft, :null => false, :index => true
t.integer :rgt, :null => false, :index => true
# optional fields
t.integer :depth, :null => false, :default => 0
t.integer :children_count, :null => false, :default => 0
end
end
def self.down
drop_table :categories
end
end
# app/models/category.rb
class Category < ActiveRecord::Base
acts_as_nested_set
end
So in order to fetch all those children nodes at the bottom of the tree you can use the leaves
method provided by the gem.
# We fetch a (random) instance of Category
my_category = Category.first
# Getting the last nodes in the tree (nodes with no children)
my_category.leaves
If you want to see what other query methods are available, you can check out the Advanced Usage section in the cheatsheet.