【发布时间】:2013-04-07 03:59:36
【问题描述】:
我认为有以下代码:
<% if @user.get_products.any? %>
<%= f.select('products', @user.get_products.collect { |user| [user.name, user.id]}) %>
get_products 对 DB 进行 ActiveRecord 查询。所以我想知道它是否真的执行两个相同的查询或在第二次调用时使用第一个查询的缓存结果?我试图在服务器日志中检查它 - 但什么也没找到。我还想知道我是否可以以某种方式控制这种行为,即为此视图设置/取消设置缓存。
谢谢!
更新:
我认为它也违反了 MVC,但让我感到困惑的是 IDE 警告:“视图不应与控制器共享两个以上的变量。”
但是,我正在创建有点“单页”的网站,所以我需要在同一视图中拥有 @user、@nearest_users 和 @user_products。于是我找到了下面这篇文章:
http://matthewpaulmoore.com/post/5190436725/ruby-on-rails-code-quality-checklist#instances
说的是
每个控制器之间只共享一个或两个实例变量 并查看。
实例变量地狱 - 当很多实例变量被共享时 在控制器和视图之间 - 在 Rails 中很容易做到。这也是 对性能有潜在危险,因为你最终可能会 在不知不觉中重复调用关联。相反,您的控制器 应该只管理一个实例变量 - 也许第二个 当前用户。这样,所有对关联的调用都加载“on” 需求”,并且可以在一个地方缓存实例变量。
这种方法也适用于片段缓存,因为您 可以在实际加载关联之前检查视图中的缓存。
例如,不是让您的博客控制器创建一个实例 @post 和 @related_posts 的变量,只需创建一个方法, @post,并给你的 Post 模型一个 related_posts 方法,这样你就可以 只需在您的视图中调用@post.related_posts。
【问题讨论】:
-
这通常被视为一种不好的做法,因为它违反了 MVC 和 Liskov 替换。尝试使用您的控制器或助手访问 ActiveRecord。也许您应该分配@products,您可能会发现更细粒度的测试存在问题。
-
如果您查看服务器日志,您应该会看到蓝色的查询表示已查询,紫色表示已缓存。惯例是只使用
products而不是get_productsbtw
标签: ruby-on-rails ruby caching activerecord