`
yuyijq
  • 浏览: 6343 次
社区版块
存档分类
最新评论

rails中用单表继承处理OO中的继承树

阅读更多

正在用rails作一个项目,在处理会员的时候遇到这样的情况。

本系统有普通会员、学生会员、教师会员、企业会员、系统管理员,各个会员有共同的属性也有自己特有的属性,是一个明显的继承关系。开始我是这样作的:

建立一个用户表users,这个表存储各种类别会员公有属性:username,password,email
然后建立students,teachers,enterprises等表,这些表里保存各会员特有的属性,然后这些表里用user_id与users表相关联,这是一个常规的数据库设计,但是在程序上处理起来却很麻烦,弄几个表,而且以后如果再多一种会员类型那是不是还要建立一个表呢?
终于发现了rails里面的单表继承:rails里的单表继承将继承体系里的所有类都映射到一个表,所有类的属性都保存在一个表里面,还有一个名字为type(又是一个约定)用于保存当前的这条记录对应的对象是属于哪个类型,那看看我所遇到的问题怎样用单表继承来解决呢:

继承体系的代码
  1. #表名users   
  2. class User < ActiveRecord::Base   
  3. end  
  4.   
  5. class Student < User   
  6. end  
  7.   
  8. class Teacher < User   
  9. end  
  10.   
  11. class Enterprise < User   
  12. end  

加入公有字段为username,password,email
Student有 student_name,student_no
Teacher有teacher_name,teacher_department
Enterprise有enterprise_address,enterprise_zip

那我们怎么设计数据库呢?

列名 备注
id  
type 约定
username 公有,用户名
password 密码
email 邮件
student_name 学生姓名
student_no 学号
teacher_name 教师姓名
teacher_department 部门
enterprise_address 企业地址
enterprise_zip 邮编

Ok,现在我们来执行这样一个代码

  1. Student.create(:name => 'yuyijq',:password => '123456',:email => 'yuyijq@hotmail.com',:   
  2.   :student_name => 'YuYi',:student_no => '03041317')  

执行后我们的数据库应该是怎样的一个情况呢?

id type username password email student_name student_no teacher_name teacher_department enterprise_address enterprise_zip
1 Student yuyijq 123456 yuyijq#hotmail.com YuYi 03041317        

再看看这样的代码

  1. #用他们的父类去查询   
  2. user = User.find(1)   
  3. #my_type结果是Student呢   
  4. my_type = user.class    

ActiveRecord会自动的去查找type这个字段,然后根据这个字段来创建对应类型的对象(好智能啊)。

从上面可以看出:
第一:除非这个字段是所有对象都公有的,那么其他字段应该设置为“可为空”,不然就要抛异常了啊
第二:看看我的student,teacher等的属性名字是不是太长了,这是因为用单表继承的时候不能使用相同名字的属性,不然谁分的清楚啊
第三:我在插入Student对象的时候也给teacher_name赋值一下,那这个Student对象不也有了teacher_name属性吗?赫赫,自己try一下

分享到:
评论
2 楼 yuyijq 2007-07-11  
哦,我这里仅仅为了说明单表继承,没有考虑到数据库设计的合理性~~Sorry!
1 楼 blackanger 2007-07-06  
username和studentname不一样吗?感觉很牵强的分离出来不同的属性,什么studentname和teatchername其实是可以合并成公有的吧

相关推荐

Global site tag (gtag.js) - Google Analytics