列与属性

Active Record 对象对应数据库表中的行。对象的属性对应表中的列。你可能已经注意
到我们定义的Order 类并没有提到orders 表中任何列。这是因为Active Record 是在运行期
间动态决定它们。Active Record 在数据库端的schema 上反射,以配置包装表的类。[这不
是严格的事实,就像一个model 可以有不是schema 的一部分的属性。我们在272 页的下一章
将祥细讨论。]
我们的表orders 可能是如下SQL 语句创建的。
create table orders (
id int not null auto_increment,
name varchar(100) not null,
email varchar(255) not null,
address text not null,
pay_type char(10) not null,
shipped_at datetime null,
primary key (id)
);
我们创建一个包装这个表的Active Record 类。
require 'rubygems'
require_gem 'activerecord'
# Connection code omitted...
class Order < ActiveRecord::Base
end
一旦我们定义了Order 类,我们就可以查询到它包含的属性(列)的信息。下面的代码使
用了columns()方法,它返回一个Column 对象数组。这里我们只显示orders 表的每个列的
名字,通过一个hash 导出shipped_at 这个列的细节。
require 'pp'
pp Order.columns.map { |col| col.name }
pp Order.columns_hash['shipped_at']
当我们运行这段代码时,我们得到以下输出。
["id", "name", "email", "address", "pay_type", "shipped_at"]
#<ActiveRecord::ConnectionAdapters::Column:0x10e4a50
@default=nil,
@limit=nil,
@name="shipped_at",
@type=:datetime>
注意:Active Record 决定每列的类型。在这个例子中,它已经知道数据库中的
shipped_at 列是一个datetime 类型。它将从这个列得到的值存放在Ruby 内的Time 对象中。
我们可以通过写入一个时间字符串到这个属性,然后再取回此内容来验证。你会发现它们返
回的是Ruby 的Time 对象。
order = Order.new
order.shipped_at = "2005-03-04 12:34"
pp order.shipped_at.class
pp order.shipped_at
它会产生:
Time
Fri Mar 04 12:34:00 CST 2005
图14.1 显示了SQL 类型和它们的ruby 表达方式之间的的映射关系。通常这个映射关系
是显而易见的。只有一个潜在的与decimal 列有关的问题。schema 设计者会使用decimal 列
来存储带有固定小数位的数字--decimal 列要求十分精确。Active Record 把decimal 列映射
为Float 类。尽管这对大多数程序是可行的,但是浮点数字是不精确的,如果在这个类型的
属性上执行一系列操作,可能会发生四舍五入的问题。你也可能想使用多个integer 列来替
代,存储货币值的各单元,分,角,元等。另一种做法是使用聚合来构造Money 对象以便分
离数据库的列(dollars 和cents,pounds 和pence,等)。
访问属性
如果一个model 对象有个属性名为balance,你可以使用索引操作符,传递给它一个字
符串或一个符号(symbol)来访问这个属性的值。这儿是我们将使用的符号。
account[:balance] #=> return current value
account[:balance] = 0.0 #=> set value of balance
尽管,在普通编码中不赞成这样使用,但是它可能会减少你的选择,当将来你可能对属
性基础实现进行修改时。相反,你应该访问值或使用Ruby 存取器方法来访问model 属性。
account.balance #=> return current value
account.balance = 0.0 #=> set value of balance
使用这两种技术返回的值,如果可能话将被Active Record 强制转换一个适当的Ruby 类
型(所以,例如,如果数据列是个timestamp,则一个Time 对象将会被返回)。如果你想获得
一个属性的原始值,append_before_type_case 方法返回它的名字,像下面代码显示的。
account.balance_before_type_cast #=> "123.4", a string
account.release_date_before_type_cast #=> "20050301"
最后,在model 本身的代码内部,你可使用read_attribute()和write_attribute()私
有方法。这些接受做为字符串参数的属性的名字。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值