正在用rails作一个项目,在处理会员的时候遇到这样的情况。
本系统有普通会员、学生会员、教师会员、企业会员、系统管理员,各个会员有共同的属性也有自己特有的属性,是一个明显的继承关系。开始我是这样作的:
建立一个用户表users,这个表存储各种类别会员公有属性:username,password,email
然后建立students,teachers,enterprises等表,这些表里保存各会员特有的属性,然后这些表里用user_id与users表相关联,这是一个常规的数据库设计,但是在程序上处理起来却很麻烦,弄几个表,而且以后如果再多一种会员类型那是不是还要建立一个表呢?
终于发现了rails里面的单表继承:rails里的单表继承将继承体系里的所有类都映射到一个表,所有类的属性都保存在一个表里面,还有一个名字为type(又是一个约定)用于保存当前的这条记录对应的对象是属于哪个类型,那看看我所遇到的问题怎样用单表继承来解决呢:
- #表名users
- class User < ActiveRecord::Base
- end
- class Student < User
- end
- class Teacher < User
- end
- class Enterprise < User
- end
加入公有字段为username,password,email
Student有 student_name,student_no
Teacher有teacher_name,teacher_department
Enterprise有enterprise_address,enterprise_zip
那我们怎么设计数据库呢?
列名 | 备注 |
id | |
type | 约定 |
username | 公有,用户名 |
password | 密码 |
邮件 | |
student_name | 学生姓名 |
student_no | 学号 |
teacher_name | 教师姓名 |
teacher_department | 部门 |
enterprise_address | 企业地址 |
enterprise_zip | 邮编 |
- Student.create(:name => 'yuyijq',:password => '123456',:email => 'yuyijq@hotmail.com',:
- :student_name => 'YuYi',:student_no => '03041317')
执行后我们的数据库应该是怎样的一个情况呢?
id | type | username | password | student_name | student_no | teacher_name | teacher_department | enterprise_address | enterprise_zip | |
1 | Student | yuyijq | 123456 | yuyijq#hotmail.com | YuYi | 03041317 |
再看看这样的代码
- #用他们的父类去查询
- user = User.find(1)
- #my_type结果是Student呢
- my_type = user.class
ActiveRecord会自动的去查找type这个字段,然后根据这个字段来创建对应类型的对象(好智能啊)。
从上面可以看出:
第一:除非这个字段是所有对象都公有的,那么其他字段应该设置为“可为空”,不然就要抛异常了啊
第二:看看我的student,teacher等的属性名字是不是太长了,这是因为用单表继承的时候不能使用相同名字的属性,不然谁分的清楚啊
第三:我在插入Student对象的时候也给teacher_name赋值一下,那这个Student对象不也有了teacher_name属性吗?赫赫,自己try一下