This post originated from an RSS feed registered with Ruby Buzz
by Bob Silva.
Original Post: Implement acts_as_threaded without a plugin
Feed Title: Rails Video Tutorials
Feed URL: http://www.railtie.net/xml/rss/feed.xml
Feed Description: A growing collection of screencasts that show you how to use the many facets of the wonderful world of rails.
It's been awhile since I've posted so I thought I'd toss this out there. If you've used my acts_as_threaded plugin, you know its an off-shoot from the acts_as_nested set inside of AR itself. I've managed to create the same functionality without the use of a plugin using the native acts_as_nested_set feature of AR. The relevant code is below. The threading functionality has been moved to the model now, add the following code to your model and you are set.
acts_as_nested_set :scope => :root
def before_create
# Update the child object with its parents attrs
unless self[:parent_id].to_i.zero?
self[:depth] = parent[:depth] + 1
self[:root_id] = parent[:root_id]
end
end
def after_create
# Update the parent root_id with its id
if self[:parent_id].to_i.zero?
self[:root_id] = self[:id]
self.save
else
parent.add_child self
end
end
def parent
@parent ||= self.class.find(self[:parent_id])
end
Your database schema will need to have the following definition:
The trick from this point, is that whenever you create a new thread, if it has a parent_id, then it will automatically be added as a child to that parent record. Otherwise, it will be set as a root thread. This version no longer requires that the fields have a default value of 0 relying on the fact that 'NilClass.to_i == 0'.
Hope you enjoy this, it's come in very handy for modeling structured content in some of my apps (like categories and multi-level organizations).