Let\'s say I have a comment model:
class Comment < ActiveRecord::Base
has_many :replies, class: \"Comment\", foreign_key: \"reply_id\"
end
I've had various generally bad experience with the different hierarchy gems available for ActiveRecord. Typically you do not want to do this yourself as your queries will end up being very inefficient.
The Ancestry gem was ok, but I had to move away from it because 'children' is a scope and NOT an association. This means you CANNOT use nested attributes with it because nested attributes only work with associations, not scopes. That may or may not be a problem depending on what you are doing, such as ordering or updating siblings through the parent or updating entire subtrees/graphs in a single operation.
The most efficient ActiveRecord gem for this is the Closure Tree gem and I had good results with it, with the caveat that splatting/ mutating entire sub-trees was diabolical because of the way ActiveRecord works. If you don't need to compute things over a tree when doing updates then it is the way to go.
I've since moved away from ActiveRecord to Sequel and it has recursive common table expression (RCTE) support which is used by its built-in tree plugin. An RCTE tree is as fast as is theoretically possible to update (just modify a single parent_id as in a naive implementation) and querying is also typically orders of magnitude faster than other approaches because of the SQL RCTE feature it uses. It is also the most space efficient approach since there is just parent_id to maintain. I am not aware of any ActiveRecord solutions that support RCTE trees because ActiveRecord doesn't cover nearly as much of the SQL spectrum that Sequel does.
If you're not wedded to ActiveRecord then Sequel and Postgres is a formidable combination IMO. You will find out the deficiencies in AR when your queries become ever so slightly complex. There is always pain moving to another ORM as its not the out of the box stock rails approach but I have been able to express queries that I couldn't do with ActiveRecord or ARel (even though they were pretty simple), and generally improved query performance across the board 10-20 times over what I was getting with ActiveRecord. In my use case with maintaining trees of data its hundreds of times faster. That means tens to hundreds times less server infrastructure I need for the same load. Think about it.
Would using a nested set still count as 'from scratch'?
The short description of a nested set is a database-specific strategy of querying hierarchies by storing/querying pre- and post-order tree traversal counts.
A picture is worth a thousand words (see also, the wikipedia page on nested sets).
There are a bunch of nested set gems, and I can personally speak for the quality of Awesome Nested Set and Ancestry
Then, Awesome Nested Set (I know from experience, presumably Ancestry too) provide helpers to do a single query to pull up all records under a tree, and iterate through the tree in sorted depth-first order, passing in the level while you go.
The view code for Awesome Nested Set would be something like:
<% Comment.each_with_level(@post.comments.self_and_descendants) do |comment, level| %>
<div style="margin-left: <%= level * 50 %>px">
<%= comment.body %>
<%# etc %>
</div>
<% end %>
I just made that up from vague memories, and it's been a while, so this is where it can be "an exercise for the reader"
You'd collect the reply's replies within each Reply iteration.
<% comment.replies do |reply| %>
<%= reply.content %>
<% reply_replies = Post.where("reply_id = #{reply.id}").all %>
<% reply_replies .each do |p| %>
<%= p.post %>
<% end
<% end %>
Though im not sure if it'd be the most conventional way cost-wise.