`
xusaomaiss
  • 浏览: 615523 次
  • 性别: Icon_minigender_1
  • 来自: 厦门
社区版块
存档分类
最新评论

我对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_treerder => "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,           
           n_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 模式》一文
分享到:
评论
1 楼 liusong1111 2007-05-01  
楼主把源代码部份排下版多好,整得都没心情看下去了。

《应用rails进行敏捷WEB开发》一书中对acts_as_tree的讲解有个小错误。
书中是这么说的:

引用

class Category < ActiveRecord::Base
  acts_as_tree : order => 'name'
end


等价于
class Category < ActiveRecord::Base
  belongs_to :parent,
             :class_name  => 'Category'
  has_many   :children,
             :class_name  => 'Category',
             :foreign_key => 'parent_id',
             : order      => 'name',
             :dependent   => true
end



其实等价式belongs_to部份也必须声明 :foreign_key => 'parent_id' ,这点书中遗漏了。因为foreign_key如不特意设定,则按:class_name选项推导,从而出错了(成了'category_id'而非预期的'parent_id')。

附带说, :dependent => true 的表达方式过期了,选项不要再用true/false,而要从 :destroy,:delete_all,:nullify三者选其一,详情查看rails API doc。



相关推荐

    acts_as_authenticated

    "acts_as_authenticated" 是一个经典的Ruby on Rails插件,它为Rails应用提供了用户认证功能。在Rails框架中,用户认证通常涉及验证用户身份、管理会话以及处理登录和登出等操作。acts_as_authenticated插件简化了这...

    acts_as_category:想想acts_as_tree +权限

    #ActsAsCategory acts_as_category (Version 2.0 beta)acts_as_category,是acts_as插件在acts_as_tree风格的Ruby on Rails的ActiveRecord的模式,但有一些额外的功能,以及多种便捷视图助手。例子(有关实例方法和...

    acts_as_list.rar

    acts_as_list.raracts_as_list.raracts_as_list.raracts_as_list.raracts_as_list.raracts_as_list.raracts_as_list.raracts_as_list.raracts_as_list.raracts_as_list.raracts_as_list.raracts_as_list.raracts_as_...

    acts_as_paranoid

    对于开发工具而言,理解`acts_as_paranoid`的工作原理并熟悉其提供的方法,可以帮助开发者更好地控制数据的生命周期,避免因误删导致的数据损失。在调试和分析数据时,可以利用软删除的特性找回已“删除”的数据。 ...

    acts_as_list, 用于管理列表的ActiveRecord插件.zip

    acts_as_list, 用于管理列表的ActiveRecord插件 ActsAsList描述这个 acts_as 扩展提供了对列表中的多个对象进行排序和重新排序的功能。 具有指定的类的类需要在映射的数据库表上定义为整数的position 列。 0.8.0升级...

    用acts_as_rateable实现简单的打分功能

    在Ruby on Rails框架中,`acts_as_rateable`是一个非常实用的插件,它允许用户对模型进行评分,从而实现简单的打分功能。这个插件是Rails社区中的一个开源项目,旨在简化应用中的评分系统集成。在本篇讨论中,我们将...

    Api-acts_as_api.zip

    Api-acts_as_api.zip,使在rails中创建api响应变得简单和有趣,一个api可以被认为是多个软件设备之间通信的指导手册。例如,api可用于web应用程序之间的数据库通信。通过提取实现并将数据放弃到对象中,api简化了编程...

    acts_as_nested_set的增强版BetterNestedSet

    《深入理解BetterNestedSet:acts_as_nested_set的增强版》 在Ruby on Rails开发中,数据结构的选择对于数据库操作的效率至关重要。其中,Nested Set模型是一种常用的数据组织方式,尤其适用于管理具有层级关系的...

    acts_as_sane_tree:用于ActiveRecord和PostgreSQLSane树构建器

    acts_as_sane_tree (用一些理智的方法建造树木) 在Postgresql&gt; = 8.4的系统上,这是对act_as_tree的替代。这提供了什么 建立树木的快速方法。哪个版本的 轨道〜&gt; 4.1.0 轨道〜&gt; 4.0.0 导轨〜&gt; 3.2.0 轨道〜&gt; 3.1.0...

    active_record-acts_as, 模拟activerecord模型的多表继承.zip

    active_record-acts_as, 模拟activerecord模型的多表继承 插件开发已经移动这个项目的积极发展已经转移到了的krautcomputing fork 。... ActiveRecord::ActsAs这是对 acts_as_relation的重构。模拟用于Acti

    rails_admin_acts_as_list:rails_admin插件以对记录进行排序

    介绍插件,用于对记录进行排序(使用 gem)安装要启用rails_admin_acts_as_list,请将以下内容添加到您的Gemfile : gem 'rails_admin_acts_as_list'gem 'rails_admin' 重要提示: rails_admin_acts_as_list之前必须...

    Rails中应用Ext.tree:以中国的省市地区三级联动选择为例

    本篇文章将深入探讨如何在Rails中利用`acts_as_nested_set` gem来实现中国省市地区的三级联动选择功能。这个功能常见于地址填写、配送区域设定等场景,用户可以从一个下拉菜单中逐级选择省、市、区,每一级的选择...

    acts_as_paranoid:ActiveRecord插件可让您隐藏和还原记录,而无需实际删除它们

    使徒行传 一个Rails插件来添加软删除。...用法安装gem: gem 'acts_as_paranoid' , '~&gt; 0.7.0' bundle install创建迁移bin/rails generate migration AddDeletedAtToParanoiac deleted_at:datetime:index启用ActsAs

    spring-acts

    spring-acts

    Ruby-ActsAsTennant通过一个共享数据库的策略来为一个Rails应用添加多租户支持

    标题中的“Ruby-ActsAsTennant”是一个用于Ruby on Rails框架的库,它提供了多租户支持...通过这些知识点,开发者可以理解并实施Acts As Tennant,为Rails应用带来强大的多租户支持,确保数据的安全性和租户间的隔离。

    acts_as_xapian:Xapian全文搜索插件,适用于Ruby on Rails

    这个压缩包还可能包含示例代码、测试用例和文档,帮助开发者更好地理解和使用acts_as_xapian。 总的来说,acts_as_xapian是Rails开发者实现全文搜索功能的一个强大工具,它的存在使得Rails应用在处理大量数据时,...

    acts_as_restful_list:就像acts_as_list一样,但很安静

    acts_as_restful_list 就像acts_as_list 一样,但不必使用非标准方法调用(如insert_at)来弄乱您的代码,acts_as_restful_list 使管理列表变得简单。 您可以像更新其他任何内容一样更新 position 属性,其余的都...

    acts_as_shopping_cart:简单的购物车实施

    acts_as_shopping_cart 一个简单的购物车实现。 您可以找到示例应用程序。 安装 滑轨3 从0.2.0版开始,不再支持Rails 3。 如果您仍需要在Rails 3应用程序中实现此gem,请使用0-1-x分支 将其包含在您的Gemfile中 ...

    acts_as_liked:向任何 Active Record 模型添加类似功能

    gem 'acts_as_liked' 然后执行: $ bundle 运行生成器: $ rails generate acts_as_liked 并且不要忘记迁移您的数据库 $ rake db:migrate 用法 可爱的模特 将acts_as_likeable添加到任何模型,它的实例可以被...

    actions_as_commentable:ActiveRecord acts_as_commentable插件

    提供单个注释模型,该模型可以附加到应用程序中的任何模型。 它创建一个Comment模型,并处理该模型与您声明为可注释模型的任何模型之间的关系。 安装: 将以下行添加到您的Gemfile中 Rails gem 'acts_as_commen...

Global site tag (gtag.js) - Google Analytics