真实世界中的Rails,第3部分: 优化ActiveRecord - 编程入门网
包括进来进一步地改进,如清单 9 所示:
清单 9: 为某个成员的联系人获取城市 member = Member.find(1) member.contacts.each {|contact| puts contact.address.city} 通过使用嵌套包含选项还能 获得更好的改进: member = Member.find(1, :include => {:contacts => :address}) member.contacts.each {|contact| puts contact.address.city} 该嵌套包含可让 Rails 热包 含 contacts 和 address 关系。一旦要在给定的查询中使用关系,就可以采用热加载技术。此技术是我 们在 ChangingThePresent.org 中使用得最为频繁的一种性能优化技术,但它还是有一些限制的。当必须 要连接两个以上的表时,最好还是采用 SQL。如果需要进行报告,最好是简单地采取数据库连接,跨过 ActiveRecord 以及 ActiveRecord::Base.execute("SELECT * FROM...")。通常来讲,热关联 足够解决问题。现在,我将转变话题,探讨 Rails 开发人员所关心的另一个麻烦问题:继承。 继 承和 Rails 当大多数 Rails 开发人员第一次接触到 Rails 时,他们就会立刻被迷住。它太简单 了。您只需在数据库表上创建一个 type 类,然后再从父类中继承子类即可。Rails 会负责其余的事情。 比如,有一个名为 Customer 表,它可以从名为 Person 类继承。一个客户可以有 Person 的所有列,外 加信誉度和订购历史。清单 10 显示了该种解决方案的简洁之美。主表具有父类和子类的所有列。 清单 10. 实现继承 create_table "people" do |t| t.column "type", :string t.column "first_name", :string t.column "last_name", :string t.column "loyalty_number", :string end class Person < ActiveRecord::Base end class Customer < Person has_many :orders end 真实世界中的Rails,第3部分: 优化ActiveRecord(6)时间:2011-11-20在很多方面,这种解决方案都可以很好地工作。代码简单且无重复性。这些查询简单且性能 很好,因为您无需进行任何连接来访问多个子类,ActiveRecord 可以使用 type 列决定哪个记录能够返 回。 在某些方面,ActiveRecord 继承十分有限。如果已有的继承等级非常宽,继承就会失效。例 如,在 ChangingThePresent,内容有很多类型,每种类型都有自己的名称、或短或长的描述、某些常见 的表示属性以及几个定制属性。我们很希望 cause、nonprofit、gift、member、drive、registry 以及 其他一些类型的对象都能够从通用的基类中继承,以便我们能以同样的方式处理所有类型的内容。但我们 却不能如此,因为 Rails 模型将会在单一表中拥有我们所有对象模型的实质内容,这不是一个可行的解 决方案。 探索其他可选方案 我们针对此问题试验了三种解决方案。第一,我们在类自身的 表中放置每个类,使用视图为内容构建通用表。我们很快抛弃了此种解决方案,因为 Rails 不能很好地 处理数据库视图。 我们的第二个解决方案是使用简单的多态。通过这种策略,每个子类都会拥有 其自身的表。我们将通用列推入每个表。例如,比方说我需要一个名为 Content 的子类,它只包含 name 属性,以及 Gift、Cause 和 Nonprofit 子类。Gift、Nonprofit 和 Cause 都可有 name 属性。由于 Ruby 是动态类型的,所以这些子类无需从通用基类中继承。它们只需对相同的一组方法进行响应。 ChangingThePresent 在几个地方使用了多态以提供通用的行为,尤其是在处理图像的时候。 第三 种方法是提供一种通用的功能,但采用的是关联而非继承。ActiveRecord 具有一种称为多态关联的特性 ,非常适合将通用行为附加给类,完全无需继承。在之前的 Address,您已经看到了多态关联的示例。我 |
凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢! |