快速业务通道

Ruby on rails开发从头来(五十五)- ActiveRecord基础(一对一关联关系) - 编程入门网

作者 佚名技术 来源 NET编程 浏览 发布时间 2012-06-14

Ruby on rails开发从头来(五十五)- ActiveRecord基础(一对一关联关系)

时间:2011-12-04 博客园 Cure

一对一关联,或者更正确的说是一对零或一对一关联,是通过外键引用到另外一张表中的至多一条记录实现的,下图描述了orders表和invoices表的关系:

Ruby on rails开发从头来(五十五)- ActiveRecord基础(一对一关联关系) - 编程入门网

在Active Record中,要表示这样的关系需要在Order类中添加has_one:Invoice声明,并且同时在Invoice类中添加声明belongs_to:order,事实上,我们可以把这种关联关系看作是相互的,我们可以使Invoice有一个Order,也可以使Order有一个Invoice,不同的是,在将对象存储到数据库时,如果我们给一个对象赋予has_one关联给另一个既存对象,关联的对象将会自动被保存。例如:

an_invoice = Invoice.new(...)
order.invoice = an_invoice # invoice gets saved

如果我们给一个对象赋予belongs_to关联到另一个对象,那么它将不会自动被保存,例如:

order = Order.new(...)
an_invoice.order = order # Order will not be saved

还有另外一个不同点,当你给一个对象赋予has_one关联时,如果指向一个既存的子对象,这个既存对象的外键关联将会被移除,也就是清零,如下图:

Ruby on rails开发从头来(五十五)- ActiveRecord基础(一对一关联关系) - 编程入门网

Ruby on rails开发从头来(五十五)- ActiveRecord基础(一对一关联关系)(2)

时间:2011-12-04 博客园 Cure

还有一个危险的地方,如果子记录不能被保存(没有通过验证等),Active Record也不会有抱怨,你也不会得到任何信息来指示该记录没有添加到数据库,所以,我们强烈推荐使用下面的方法:

invoice = Invoice.new
# fill in the invoice
unless invoice.save!
an_order.invoice = invoice

因为save!方法在失败的时候会抛出异常,这样我们就知道发生了什么。

belongs_to声明

belongs_to声明给一个类指定父关联,Active Record约定在这个表中包含有引用到另一个表的外键,父类的名字假定为混合大小写,且单数,外键字段为单数,并且在末尾添加_id,所以,下面的代码:

class LineItem < ActiveRecord::Base
belongs_to :product
belongs_to :invoice_item
end

Active Record关联line item到类Product和InvoiceItem,在底层,使用外键product_id和invoice_item_id关联到products和invoice_items表的id列。也可以像下面这样,给belongs_to一个哈希(hash):

class LineItem < ActiveRecord::Base
belongs_to :paid_order,
:class_name => "Order",
:foreign_key => "order_id",
:conditions => "paid_on is not null"
end

在上面的代码里,我们创建了一个关联,叫做paid_order,引用了Order类,通过order_id关联,并且paid_on字段不为null,在这种情况下,我们的关联不直接映射到line_items表的单一的列。belongs_to()方法创建了一组实例方法来管理关联,方法名都以关联的名字开头,例如:

item = LineItem.find(2)
# item.product is the associated Product object
puts "Current product is #{item.product.id}"     
puts item.product.title
item.product = Product.new(:title => "Advanced Rails",
:description => "...",
:image_url => "http://....jpg",
:price => 34.95,
:date_available => Time.now)
item.save!
puts "New product is #{item.product.id}"
puts item.product.title

运行后我们会得到下面的输出:

Current product is 2
Programming Ruby
New product is 37
Advanced Rails

Ruby on rails开发从头来(五十五)- ActiveRecord基础(一对一关联关系)(3)

时间:2011-12-04 博客园 Cure

我们使用了在LineItem类中生成的

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号