一些快要被我遗忘的rails特性.(1.单表继承)

本文介绍了如何在Rails项目中使用单表继承(STI)技术,通过一个具体示例展示了如何设计数据库表结构,并实现了不同子类的数据存储。此外,还讨论了单表继承的优缺点。
有段时间没做Rails项目了, 最近准备开始一个新的Rails项目.简单的复习了一下,才发现的确有一些相对少用的特性已经有点遗忘.在此做个记录,也算加深个映像.

Rails中实现单表继承(Single-Table Inheritance)
单表继承这个概念其实是要解决面向对象与关系数据库的一个矛盾或者说不同.在关系数据库中我们并没有继承这个概念.
而单表集成解决这个问题的方式是,将父类和所有子类的属性的并集全部存入一张数据库表中,同时加入一个type字段(Rails默认其为type),来区别此条记录是属于哪一个子类的对象.
下面我举个简单的例子:

create_table :people do |t|
t.string :type
#公共属性
t.string :name
t.string :email

#manager的属性:分红
t.decimal :bonus, :precision => 10, :scale => 2

#developer的属性: 电脑补助
t.decimal :subsidy, :precision => 4, :scale => 2

#customer属性: 地址
t.string :address

t.timestamps
end


model:


#person.rb
class Person < ActiveRecord::Base
end

#employee.rb
class Employee < Person
belongs_to :manager, :class_name => "Employee"
end

#manager.rb
class Manager < Employee
end

#customer.rb
class Customer < Person
end


script/console
>> m = Manager.create(:name => 'Calvin', :email => 'calvin@god.com', :bonus => 100000.00, :subsidy => 200.00)

>> e = Employee.new(:name => 'Terry', :email => 'Terry@god.com',:subsidy => 200.00)
>>e.manager = m

>>c = Customer.create(:name => 'Gates', :email => 'Gates@god.com', :address => 'USA')

此时我们可以看看数据库:

[img]http://dl.iteye.com/upload/attachment/142487/3ccc5fd0-33f9-3f74-abe5-e600c1cfcf05.png[/img]

然后我们可以做一些查询.

>> m = Person.find_by_name("Calvin")
=> #<Manager id: 1, type: "Manager", name: "Calvin", email: "calvin@god.com", bonus: #<BigDecimal:23c17c8,'0.1E6',4(12)>, subsidy: #<BigDecimal:23c178c,'0.2E3',4(8)>, manager_id: nil, address: nil, created_at: "2009-09-03 09:47:40", updated_at: "2009-09-03 09:47:40">

>> e = Employee.find_by_name("Terry")
=> #<Employee id: 2, type: "Employee", name: "Terry", email: "Terry@god.com", bonus: nil, subsidy: #<BigDecimal:237fc9c,'0.2E3',4(8)>, manager_id: 1, address: nil, created_at: "2009-09-03 09:55:54", updated_at: "2009-09-03 09:56:24">

>> e.manager
=> #<Manager id: 1, type: "Manager", name: "Calvin", email: "calvin@god.com", bonus: #<BigDecimal:237a418,'0.1E6',4(12)>, subsidy: #<BigDecimal:237a3dc,'0.2E3',4(8)>, manager_id: nil, address: nil, created_at: "2009-09-03 09:47:40", updated_at: "2009-09-03 09:47:40">

最后我们来看看,单表继承的利弊.

好处自不用说,我们用一张表就能存储所有子类的信息.不用为每一个子类创建常见一张表,从数据库的设计角度来讲,可以说是简洁了许多.

但是缺点也很明显每条记录都拥有所有子类的属性,冗余显得比较大.

按DHH的话来说, 这没有一个标准的选择, 只是一种取舍. 他更倾向于用单表继承而已.

关于单表继承更详细的一些阐述也可以参见Martin Fowler的<<企业应用架构模式>>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值