Implement acts_as_threaded without a plugin 30
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.
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).
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].to_i + 1
self[:root_id] = parent[:root_id].to_i
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
create_table "my_table_name", :force => true do |t| t.column "root_id", :integer t.column "parent_id", :integer t.column "lft", :integer t.column "rgt", :integer t.column "depth", :integer end
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).
def before_create unless self[:parent_id].to_i.zero? self[:depth] = parent[:depth].to_i + 1 self[:root_id] = parent[:root_id].to_i end endbye emFor each post, you put it in a span/div and do style="margin: 0 0 0 "
That way the children are indented based on how deep they are (in this case, 10 pixels more indented per level)
def ancestors if root? then [] else Topic.find(:all, :conditions => "id = #{root_id} or " + "(root_id = #{root_id} and depth < #{depth} " + "and #{left_col_name} < #{self[left_col_name]} " + "and #{right_col_name} > #{self[right_col_name]})", :order => 'depth') end end