acts_as_nested_set的增强版BetterNestedSet

BetterNestedSet 插件是nested_set的增加版。不仅多了一些方法,而且结构更加精简,查询更方便。

==[b]安装[/b]

script/plugin install svn://rubyforge.org/var/svn/betternestedset/trunk


==[b]数据结构[/b]

例子:
root
|_ Child 1
|_ Child 1.1
|_ Child 1.2
|_ Child 2
|_ Child 2.1
|_ Child 2.2

形象的表示如下图所示:
___________________________________________________________________
| Root |
| ____________________________ ____________________________ |
| | Child 1 | | Child 2 | |
| | __________ _________ | | __________ _________ | |
| | | C 1.1 | | C 1.2 | | | | C 2.1 | | C 2.2 | | |
1 2 3_________4 5________6 7 8 9_________10 11_______12 13 14
| |___________________________| |___________________________| |
|___________________________________________________________________|

数据表:

id | parent_id | lft | rgt | data
1 | | 1 | 14 | root
2 | 1 | 2 | 7 | Child 1
3 | 2 | 3 | 4 | Child 1.1
4 | 2 | 5 | 6 | Child 1.2
5 | 1 | 8 | 13 | Child 2
6 | 5 | 9 | 10 | Child 2.1
7 | 5 | 11 | 12 | Child 2.2

必要的字段:[color=red]parent_id[/color],[color=red]lft[/color],[color=red]rgt[/color]。
数据迁移脚本如下:

# TAITO BetterNestedSet Mig
class CreateCategories < ActiveRecord::Migration
def self.up
create_table :categories do |t|
t.column :name, :string, :null=>false
t.column :parent_id, :integer
t.column :lft, :integer
t.column :rgt, :integer
end
end

def self.down
drop_table :categories
end
end


=Model中
class Category < ActiveRecord::Base
acts_as_nested_set
end


数据的建立和acts_as_nested_set差不多。唯一的区别是添加子级的方法不一样:

如:
root = Category.create(:name => "root")
child = Category.create(:name => "child")

child.move_to_child_of root # 移动过去



==[b]更多实用方法[/b]

[b]root[/b] - root item of the tree (the one that has a nil parent; should have left_column = 1 too)
[b]roots[/b] - root items, in case of multiple roots (the ones that have a nil parent)
[b]level[/b] - number indicating the level, a root being level 0
[b]ancestors[/b] - array of all parents, with root as first item
[b]self_and_ancestors[/b] - array of all parents and self
[b]siblings[/b] - array of all siblings, that are the items sharing the same parent and level
[b]self_and_siblings[/b] - array of itself and all siblings
[b]children_count[/b] - count of all immediate children
[b]children[/b] - array of all immediate childrens
[b]all_children[/b] - array of all children and nested children
[b]full_set[/b] - array of itself and all children and nested children

==[b]原创的辅助方法[/b]
module NestedSetList  
def first?
parent.nil? or parent.lft==self.lft-1
end
def last?
parent.nil? or parent.rgt==self.rgt+1
end
def higher_item
list = self_and_siblings
i = list.index(self)
i==0 ? self : list[ i-1 ]
end
def lower_item
list = self_and_siblings
i = list.index(self)
i==list.size-1 ? self : list[ i+1 ]
end
def move_higher
move_to_left_of( higher_item ) if higher_item
end
def move_lower
move_to_right_of( lower_item ) if lower_item
end
def move_to_top
move_to_left_of( self_and_siblings.first )
end
def move_to_bottom
move_to_right_of( self_and_siblings.last )
end
end


在model中调用:
[color=blue]include NestedSetList[/color]

==[b]注意[/b]

Rails 2.1版本下使用,会有错误,这是因为2.1对于 attributes_with_quotes ,发生了很大变化。

[color=green]BetterNestedSet Rails2.1 ArgumentError [/color]

请修改插件lib/better_nested_set.rb 文件的这一段
......
def attributes_with_quotes(include_primary_key = true, include_readonly_attributes = true, attribute_names = @attributes.keys)
left_and_right_column = [acts_as_nested_set_options[:left_column], acts_as_nested_set_options[:right_column]]
quoted = {}
connection = self.class.connection
attribute_names.each do |name|
if column = column_for_attribute(name)
quoted[name] = connection.quote(read_attribute(name), column) unless !include_primary_key && (column.primary || left_and_right_column.include?(column.name))
end
end
include_readonly_attributes ? quoted : remove_readonly_attributes(quoted)
end
......

==其它

acts as section map 是一个针对acts树结构的一个扩展插件。可以生成表格形式的结构图.

=安装方法
./script/plugin install http://xibbar.net/svn/rails/plugins/trunk/acts_as_section_map/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值