Ruby for Rails 最佳实践十四

第四部分 结合 Ruby 和 Rails

第十四章 再次为 R4RMusic 应用领域建模

一、跟踪 ActiveRecord 模型实例的功能

1. 模型实例功能概览:Rails 模型实例的功能来源于四个地方

■ 通过实例所属的类继承,该实例可以调用所属类的父类(即 ActiveRecord::Base 或该类的另外一个后代)的实例方法。

■ 根据相关的数据库表的字段名自动生成的读写方法(accessor)和其它方法。举例来说,由于数据库表 composers 中有 title 字段,所以 Composer 的对象具有 title 和 title= 方法。

■ 在使用关联指令时,半自动生成的读写方法和其它方法。例如,在 Work 类中的 has_one: composer。

■ 通过编程添加的任意多个实例方法,它们根据需要被添加到模型定义文件中。

 

2. 继承的和自动获得的 ActiveRecord 模型实例行为

(1)ActiveRecord 对象的两种存在方式

ActiveRecord 和典型的 Ruby 对象之间是有差别的,ActiveRecord 对象有两种存在方式:一方面,它是一个 Ruby 类。另一方面,它是一个句柄,可以用它来直接操作数据库记录。

 

ActiveRecord 的类方法和实例方法,以及它们与对象和数据库记录的存在状态之间的关系

 

 

new

create

(new+save)

find

save

update

delete

(find+destroy)

destroy

方法调用前:

Ruby 对象存在吗?

不存在

不存在

不存在

存在

存在

不存在

存在

数据库记录存在吗?

不存在

不存在

存在

存在

存在

存在

存在

方法调用后:

Ruby 对象存在吗?

存在

存在

存在

存在

存在

存在

冻结

存在

冻结

数据库记录存在吗?

不存在

存在

存在

存在

存在

不存在

不存在

 

 

■ 方法被调用前没有对象存在的方法是类方法(可以根据没有对象实例调用它们来判断)。

■ 冻结意味着已经通过 Ruby 的 freeze 方法将对象实例冻结。这保证对象不会再被改变,不能再给它的实例变量赋值。在销毁一个 ActiveRecord 对象后,它会被冻结。尽管可以从数据库中彻底删除记录,但是 Ruby 中没有相应的可以彻底地删除对象的操作。因此,冻结它就是最好的指示它的生命期已经结束的方法。

■ update、delete 和 destroy 各自有一个以 _all 结尾的变体(update_all 等),它们对数据库中所有已存的记录或相应的 Ruby 实例执行给定的操作。

 

(2)根据数据库中的字段名自动生成的方法

ActiveRecord 将数据库的结构和名字都映射到 Ruby 中,将表名映射为类名,字段名映射为实例方法。Rails 是一个对象关系映射系统(ORM,Object/Relational Mapping)。

 

3. 通过关联半自动获得的行为

关联准确生动地描述了 Rails 实体模型之间的“有”和“属于”关系。如 Composer 类中包含 has_many :works,以及 Work 类中包含 belongs_to :composer。

 

我们没有定义 has_many 方法,所以它肯定是父类 ActiveRecord::Base 的类方法,其它的关联和有 belongs_to、has_one 和 has_and_belongs_to_many。

 

二、改进领域模型

1. 从 Edition 模型中抽取出 Publisher 模型,并设置发行商和版本之间的关系

F:\ruby_project\R4Rmusic>ruby script/generate model publisher

 

修改 app/models/publisher.rb 文件

class Publisher < ActiveRecord::Base

         has_many :editions

end

 

创建 publishers 数据表结构

CREATE TABLE publishers (

         id INT(11) NOT NULL AUTO_INCREMENT,

         name VARCHAR(60),

         city VARCHAR(30),

         country CHAR(2),

         PRIMARY KEY (id)

);

 

改变后的 editions 表以及新生成的 publishers 表

 

2. instruments 模型和多对多关系

(1)我们要支持按照乐器分类来浏览乐谱,因此单独创建一个乐器的数据表

F:\ruby_project\R4Rmusic>ruby script/generate model instrument

 

instruments 模型有两个属性:name(乐器名,如小提琴) 和 family(乐器族,如弦乐)

CREATE TABLE instruments (

         id INT(11) NOT NULL AUTO_INCREMENT,

         name VARCHAR(20),

         family VARCHAR(15),

         PRIMARY KEY (id)

);

 

乐器和音乐之间是多对多关系:一件作品可以被多个乐器演奏,一个乐器可以演奏多个作品。

实现多对多关系,首先要为 Rails 提供一个记录乐器和作品关系的表,并遵循 Rails 标准为这张表命名:instruments_works。它有两个字段:一个是针对特定乐器ID字段,另一个是针对特定作品的ID字段

CREATE TABLE instruments_works (

         instrument_id int(11),

         work_id int(11)

);

 

(2)使用 has_and_belongs_to_many 关联

修改 app/models/instrument.rb 中的关联指令

class Instrument < ActiveRecord::Base

         has_and_belongs_to_many :works

end

 

添加 app/models/work.rb 中的关联指令

class Work < ActiveRecord::Base

         has_and_belongs_to_many :instruments

end

 

(3)instrument 模型对 work 模型的影响

需要给 Work 模型添加基调(key)属性,但是 key 是 SQL 的关键字,所以改名为 kee。

还需要增加一个作品编号(opus)字段,现在 works 表的 SQL 如下

CREATE TABLE works (

         id INT(11) NOT NULL AUTO_INCREMENT,

         composer_id INT(11),

         title VARCHAR(100),

         year INT(4),

         kee CHAR(9),

         opus VARCHAR(20),

         PRIMARY KEY (id)

);

 

(4)editions 到 works 的多对多映射

一件作品可以出现在多个版本中,一个版本可以包含多件作品。首先把 work_id 从 editions 表中删除,然后增加一个用于保存 works 和 editions 关系的表

CREATE TABLE editions_works (

         edition_id int(11),

         work_id int(11)

);

 

修改 ActiveRecord,修改 edition.rb 中的 belongs_to :work

has_and_belongs_to_many :works

 

在 work.rb 中加入下面代码(:order 告诉 ActiveRecord 把返回的版本按年份升序排序)

has_and_belongs_to_many :editions,

                        :order => "year ASC"

 

3. 创建顾客和订单模型

(1)我们将让顾客做下面这些事:

■ 注册

■ 登录

■ 选择商品并将其放入购物车中

■ 结帐(购买商品)

 

在 Rails 方面,需要为 customer 模型生成模型和控制器

F:\ruby_project\R4Rmusic>ruby script/generate model customer

F:\ruby_project\R4Rmusic>ruby script/generate controller customer

 

在数据库方面,创建顾客模型的 SQL 表结构

CREATE TABLE customers (

         id INT(11) NOT NULL AUTO_INCREMENT,

         first_name VARCHAR(30),

         last_name VARCHAR(30),

         nick VARCHAR(15),

         password VARCHAR(40),

         email VARCHAR(50),

         PRIMARY KEY (id)

);

 

(2)创建定单模型

F:\ruby_project\R4Rmusic>ruby script/generate model order

为记录订单时间,orders 表有一个名为 created_at 字段。该字段名在 Rails 中是一个特殊的字段名:在保存 Order 对象时,Rails 自动将保存操作发生的时间和日期。Order 模型中还包含一个 status 字段,如果订单已经付过款,该字段设置为“paid”,如果订单商品已经发出,则设置为“shipped”

CREATE TABLE orders (

         id INT(11) NOT NULL AUTO_INCREMENT,

         edition_id INT(11),

         customer_id INT(11),

         status CHAR(4),

         created_at DATETIME,

         PRIMARY KEY (id)

);

 

(3)建立 orders 与 customers 和 editions 的关联

修改 app/models/orders.rb 文件

class Order < ActiveRecord::Base

         belongs_to :customer

         belongs_to :edition

end

 

修改 app/models/customer.rb 文件,并创建依赖关系:如果顾客记录不存在,那么他的订单也随之删除,一旦所属的记录被删除,这些无主记录就没有用了。

class Customer < ActiveRecord::Base

         has_many :orders,

                  :dependent => true,

                  :order     => "created_at ASC"

end

 

最后在 edition 模型中,也要为 orders 添加一个关联

class Edition < ActiveRecord::Base

         has_many :orders

end

 

4. 为订单设置默认状态

在 Order 类中定义 before_create 方法,在每次保存新模型实例时,自动调用该方法

def before_create

         self.status = "open"

end

 

5. 图示新的领域模型

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值