我对acts as tree的理解及应用

本文探讨了Rails框架下实现树型结构的方法,通过具体案例展示了如何利用acts_as_tree插件来构建和操作树型数据结构,并分享了一种展示树型结构的组件。
最近在看敏捷一书,把我对Acts as tree一节的理解写下。
前提:
手头上有《应用rails进行敏捷Web开发》一书
正文:
对书上已经提到就不重复了,在现实中树型结构的表是很多,我这里用家庭做一个例子。

表结构:
ID Parent_id name People_count
0 null root 0

Mysql脚本
DROP TABLE IF EXISTS `databasename`.`people`;
CREATE TABLE ` databasename `.`peoples` (
`id` int(11) NOT NULL auto_increment,
`parent_id` int(11) default NULL,
`name` varchar(100) NOT NULL default '',
`people_count` int(11) NOT NULL default '0',
PRIMARY KEY (`id`)
);

class Person < ActiveRecord::Base
acts_as_tree :order => "name", :counter_cache => true
def to_s
puts "id is #{id},parent_id is #{parent_id},name is #{name},children_count is #{people_count}"
end
def self.display_children(parent)
puts parent.children.map{|child| child.name}.join(",")
end

end

其中people_count是计数器,参看书:P244,用于记录节点孩子的个数.
在models类中要把:counter_cache => true
在rails.chm档中关于acts_as_tree的说明中,:counter_cahe默认值是false
acts_as_tree(options = {})
Configuration options are:
• foreign_key - specifies the column name to use for tracking of the tree (default: parent_id)
• order - makes it possible to sort the children according to this SQL snippet.
• counter_cache - keeps a count in a children_count column if set to true (default: false).

# 树型结构
# root -------------根节点
# father ------一级子节点
# daughter --二级子节点
# son --二级子节点
# mother-------一级子节点
#
在test\unit\person_test.rb中写测试函数:
def test_person
Person.delete_all #清空表内容
root = Person.create(:name=>"root")
puts root.to_s

person = root.children.create(:name=>'father')

puts person.to_s
puts root.people_count #结果是0,与预期不符
puts root.children.size #结果是1,正确

person.children.create(:name=>'daughter')
Person.display_children(person)

person.children.create(:name=>'son')
Person.display_children(person)

#创建一个临时节点,用于查看删除
person.children.create(:name=>'temp')
Person.display_children(person)

temp = Person.find_by_name('father')
puts "person people_count is : #{person.people_count}" #结果是0
puts "person people_count is : #{temp.people_count}" #结果是3

#注意我这里使用了两种不同的方式去得到孩子个数
printf "root children count is :", root.children_count()
printf "\n"
puts "person children size is :#{person.children.size}"
#得到父亲
puts "person parent name is :#{person.parent.name}"

end
通过查看表内容,记录与我们预期是一致的,当然你可以在测试时做一些错误的操作。看是否会报错。
在运行过程,注意到
puts root.people_count #结果是0,与预期不符
puts root.children.size #结果是1,正确
所以在运用时,这点要注意,事实上在数据库中people_count已经是1了,
temp = Person.find_by_name('father')
puts "person people_count is : #{person.people_count}" #结果是0
puts "person people_count is : #{temp.people_count}" #结果是3

对于这个问题,我查不到相关的资料,如果有谁知道,告诉我一下。
现在我都是使用size() 去得到记录总数

实例:
对于树我使用的是Livetree组件,
可以通过:http://www.epiphyte.ca/code/live_tree.html下载
同时,它提供了丰富的实例。
我在它的基础上做了些修改,实现了 添加同级节点,添加子节点,删除叶子节点

如果谁感觉兴趣可以发邮箱向我索要.
seaofforest@126.com
我把几个主要代码贴出来:
放在<head>与</head>之间
<script type="text/javascript">
function OnClickItem(tree, itemId, itemIsLeaf, mapId) {
alert("clicked on " + itemId);
tree.activateItem(itemId);
window.location.href="<%=url_for :controller => 'family',:action=>'show_tree' ,:id=>nil%>"+'/'+itemId
}
</script>
在body中添加用于显示树型结构:
<div style="width:300px;height:415px">
<%= live_tree(:family_tree, {
:initial_data_root => @root,
:on_click_item => "OnClickItem(this, item.id, item.isLeaf, item.isLeaf ? item.parent.id : item.id)"

}) %>
</div>
其它的添加,删除在测试代码中都有体现。如果想得到节点的层级,我现在还不知道rails有什么函数可以直接得到,但是可以通过在表中添加leve字段,用于保存节点的层级,这是我目前知道的比较简单的方法吧。

注:
阅读本文后,可以到
http://www.oracle.com/technology/global/cn/pub/articles/saternos-rails.html
查看《Rails 上的 HR 模式》一文
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值