我应该如何在视图的不同部分使用实例变量?

时间:2012-11-18 14:48:29

标签: ruby-on-rails mongodb ruby-on-rails-3 mongoid nosql

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

在我的应用程序中'我正在使用Rails 3.2.8与Mongoid和MongoDB。

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

ProgramsController< ApplicationController中

@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个查询我的观点。不是太多了吗?

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

提前致谢。

3 个答案:

答案 0 :(得分:0)

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

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

答案 1 :(得分:0)

一旦项目存储在@program中,它确实保存在那里,后续请求将不会生成查询。如果您只引用@program.title@program.content,那么您可能会没事。您的问题来自协会,例如@program.schedules@program.articles。问题是没有从@program = Program.find(params[:id])加载计划和文章。这被称为n + 1问题。 {em> Eager Loading 下的official docs州,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)

答案 2 :(得分:0)

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

Rails Official doc说: 您可以使用:include选项指定在使用此关联时应急切加载的二阶关联。

此处时间表文章一阶关联。因此,如果您使用ActiveRecord,则不需要它。

官方文件也说:

没有必要使用 :include 进行直接关联 - 也就是说,如果您有 订单belongs_to :客户 ,然后 客户在需要时自动加载。

如果您使用的是ActiveRecord,那么您可能不会打扰这个问题。