Chr*_*ssl 8 ruby sql activerecord ruby-on-rails nested-sets
我正在使用awesome_nested_set我的Rails项目中的插件.我有两个看起来像这样的模型(简化):
class Customer < ActiveRecord::Base
has_many :categories
end
class Category < ActiveRecord::Base
belongs_to :customer
# Columns in the categories table: lft, rgt and parent_id
acts_as_nested_set :scope => :customer_id
validates_presence_of :name
# Further validations...
end
Run Code Online (Sandbox Code Playgroud)
数据库中的树按预期构造.的所有值parent_id,lft以及rgt是否正确.树有多个根节点(当然允许进入awesome_nested_set).
现在,我想在一个正确排序的树中呈现给定客户的所有类别,例如结构:例如嵌套<ul>标签.这不会太难,但我需要它才能有效(sql查询越少越好).
更新:想出可以在没有进一步SQL查询的情况下计算树中任何给定节点的子节点数:number_of_children = (node.rgt - node.lft - 1)/2.这并不能解决问题,但可能会有所帮助.
如果嵌套集具有开箱即用的更好的功能将是不错的.
您发现的技巧是从平面集构建树:
见下文:
def tree_from_set(set) #set must be in order
buf = START_TAG(set[0])
stack = []
stack.push set[0]
set[1..-1].each do |node|
if stack.last.lft < node.lft < stack.last.rgt
if node.leaf? #(node.rgt - node.lft == 1)
buf << NODE_TAG(node)
else
buf << START_TAG(node)
stack.push(node)
end
else#
buf << END_TAG
stack.pop
retry
end
end
buf <<END_TAG
end
def START_TAG(node) #for example
"<li><p>#{node.name}</p><ul>"
end
def NODE_TAG(node)
"<li><p>#{node.name}</p></li>"
end
def END_TAG
"</li></ul>"
end
Run Code Online (Sandbox Code Playgroud)
自2009年9月以来,令人敬畏的嵌套集包括一个特殊的方法来执行此操作:https: //github.com/collectiveidea/awesome_nested_set/commit/9fcaaff3d6b351b11c4b40dc1f3e37f33d0a8cbe
此方法比调用级别更有效,因为它不需要任何其他数据库查询.
示例:Category.each_with_level(Category.root.self_and_descendants)do | o,level |
| 归档时间: |
|
| 查看次数: |
8115 次 |
| 最近记录: |