我们假设我们在视图中有这两个输出:
@post.user.first_name
current_user.posts.size
如果上面的输出在一个视图中被多次调用,那么Rails"足够聪明"不是每次都打到数据库?
如果答案是肯定的 - 是否有任何"一般规则"关于这个值得知道吗?
如果答案是否 - 那么一个好的做法是将关联的对象/对象存储在其自己的变量中吗?
答案 0 :(得分:1)
ActiveRecord caches queries for performance。如果您在控制台中执行AC查询几次,您将看到第二个查询由于AC缓存而执行得更快。所以我猜这也适用于视图中的查询。
您可以使用Rails Fragment Caching功能手动缓存对象。
Fragment Caching允许将视图逻辑片段包装在一个 缓存块并在下一个请求时从缓存存储中提供服务 进来了。
您也可以使用Cache Stores。
Rails为缓存数据提供了不同的存储(除了SQL之外) 和页面缓存)。
答案 1 :(得分:0)
视图的查询在呈现视图的控制器操作中完成。您会注意到在控制器操作中定义了@post
,但您可能看不到current_user
已定义。这通常是因为您使用的是设计gem,定义current_user
方法的代码是gem的一部分。
渲染视图所需的一切都应该在控制器中由ActiveRecord
查询,并在应用程序的内存中准备视图的渲染。因此,多次调用@post或current_user无关紧要。
有时通过视图的关联来调用对象,例如。 @post.user.name
将不得不查询用户。这将工作,但更好的模型 - 视图 - 控制器分离,以急切加载用户以及控制器中的帖子。遵循MVC并确保您的查询在控制器中发生也将帮助您避免N + 1查询性能问题。见Rails Active Record Query Eager Load
使用帖子查询用户的示例。
@post = Post.find(post_params).includes(:user)