我对acts as tree的理解及应用
当前位置:首页 ----> Web开发 ----> Ruby/Python
关键词:acts as tree,tree,rails,Web,end end,people count,rails chm,counter cahe,rb,delete all,root people count,Livetree,live tree html,com,itemId,body,leve,HR
xusaomaiss:
最近在看敏捷一书,把我对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  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,用于记录节点孩子的个数.  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") puts root.to_s  'father')    puts person.to_s  puts root.people_count #结果是0,与预期不符  puts root.children.size #结果是1,正确 'daughter') Person.display_children(person) 'son') Person.display_children(person) #创建一个临时节点,用于查看删除 '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 我把几个主要代码贴出来: 之间    function OnClickItem(tree, itemId, itemIsLeaf, mapId) {  alert("clicked on " + itemId);  tree.activateItem(itemId); "+'/'+itemId   }   在body中添加用于显示树型结构:  <%= live_tree(:family_tree, {  @root,   "OnClickItem(this, item.id, item.isLeaf, item.isLeaf ? item.parent.id : item.id)"   其它的添加,删除在测试代码中都有体现。假如想得到节点的层级,我现在还不知道rails有什麽函数可以直接得到,但是可以通过在表中添加leve字段,用于保存节点的层级,这是我目前知道的比较简单的方法吧。 注:  阅读本文后,可以到 http://www.oracle.com/technology/global/cn/pub/articles/saternos-rails.html 查看《Rails 上的 HR 模式》一文


liusong1111:
楼主把源代码部份排下版多好,整得都没心情看下去了。 《应用rails进行敏捷WEB开发》一书中对acts_as_tree的讲解有个小错误。 书中是这么说的: 引用  'name'
end
等价于  true
end
 'parent_id' ,这点书中遗漏了。因为foreign_key如不特意设定,则按:class_name选项推导,从而出错了(成了'category_id'而非预期的'parent_id')。  true 的表达方式过期了,选项不要再用true/false,而要从 :destroy,:delete_all,:nullify三者选其一,详情查看rails API doc。
原文出处:http://www.javaeye.com/topic/76362