2

这可能是一个菜鸟问题。但我自己无法弄清楚。

在我的应用程序中,我使用带有 Mongoid 和 MongoDB 的 Rails 3.2.8。

我有一个这样的实例变量:

程序控制器 < 应用控制器

@program = Program.find(params[:id])

在我的视图文件中,我需要多次使用它。例如;

@program.title
@program.content
@program.schedules (associated with Schedule model)
@program.articles (associated with Article model)

等等

问题是,我需要在视图的不同部分使用该实例变量。所以这不像做一个@program.each do |t| ....

但是,当我在视图的不同部分使用@program 时,这意味着每次都有一个新查询......

目前,我的观点有 31 个查询。是不是太多了?

那么最佳实践是什么?我应该如何有效地使用实例变量?

提前致谢。

4

3 回答 3

0

一旦项目存储在 中@program,它确实保存在那里,后续请求将不会生成查询。如果你只引用@program.titleand @program.content,你可能会没事。您的问题来自关联,例如@program.schedules@program.articles。问题是没有从您的@program = Program.find(params[:id]). 这被称为 n+1 问题。官方文档Eager Loading下声明了Eager loaded is supported on all relations with the exception of polymorphic belongs_to associations.In order for eager loading to work, the Identity Map must be enabled.. 如果这两个条件为真,您应该会看到查询减少。如果你不能满足这些要求,一个好的解决方案可能是在控制器中做这样的事情,提前抓住它们,在一个查询中:@schedules = Schedule.find_by(program_id: @program.id)

于 2012-11-18T15:32:38.097 回答
0

如果可能的话,我宁愿使用 ActiveRecord。

Rails 官方文档说: 您可以使用 :include 选项指定在使用此关联时应该预先加载的二阶关联。

这里schedulearticle一阶关联。因此,如果您使用 ActiveRecord,则不需要它。

官方文档还说:

无需使用 :include 进行即时关联——也就是说,如果您有 Order belongs_to :customer ,那么 客户会在需要时自动加载。

因此,如果您使用 ActiveRecord,您可能不会打扰这个问题。

于 2012-12-19T10:43:37.230 回答
0

我对 Ruby/Railys 不是特别熟悉,但通常在 MVC 框架中,数据的获取由控制器处理,因此只会发生一次。随后在视图中使用它会为请求使用缓存在内存中的单个副本。在您的视图的一个部分引用标题并在另一部分引用内容不应该是性能问题。它们只是缓存对象的属性访问器。

为了验证这一点,您可以对请求进行计时或模拟,以查看它是否实际上被执行了多次(我对此表示怀疑)。

于 2012-11-18T15:04:03.627 回答