清理控制器以加速应用程序
因此,在我的应用程序中,我有在整体布局中使用的通知和不同的记录计数,因此每个页面都需要它们。
目前在我的 application_controller 中我有很多这样的东西:
@status_al = Status.find_by_name("Alive")
@status_de = Status.find_by_name("Dead")
@status_sus = Status.find_by_name("Suspended")
@status_hid = Status.find_by_name("Hidden")
@status_arc = Status.find_by_name("Archived")
@balloon_active = Post.where(:user_id => current_user.id, :status_id => @status_al.id )
@balloon_dependent = Post.where(:user_id => current_user.id, :status_id => @status_de.id )
@balloon_upcoming = Post.where(:user_id => current_user.id, :status_id => @status_sus.id )
@balloon_deferred = Post.where(:user_id => current_user.id, :status_id => @status_hid.id )
@balloon_complete = Post.where(:user_id => current_user.id, :status_id => @status_arc.id )
.. 这实际上只是一小部分,我通过类似的调用至少将其加倍。问题是我几乎每一页都需要这些数字,但我觉得我在这里访问数据库的次数太多了。
有什么更好实施的想法吗?
So in my app I have notifications and different record counts that are used in the overall layout, and are therefore needed on every page.
Currently in my application_controller I have a lot of things like such:
@status_al = Status.find_by_name("Alive")
@status_de = Status.find_by_name("Dead")
@status_sus = Status.find_by_name("Suspended")
@status_hid = Status.find_by_name("Hidden")
@status_arc = Status.find_by_name("Archived")
@balloon_active = Post.where(:user_id => current_user.id, :status_id => @status_al.id )
@balloon_dependent = Post.where(:user_id => current_user.id, :status_id => @status_de.id )
@balloon_upcoming = Post.where(:user_id => current_user.id, :status_id => @status_sus.id )
@balloon_deferred = Post.where(:user_id => current_user.id, :status_id => @status_hid.id )
@balloon_complete = Post.where(:user_id => current_user.id, :status_id => @status_arc.id )
..
Thats really just a small piece, I have at least double this with similar calls. The issue is I need these numbers pretty much on every page, but I feel like I'm htting the DB wayyyy too many times here.
Any ideas for a better implementation?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
首先,您应该将其中的许多内容
移至范围中,这将允许您以更灵活的方式使用它们,例如使用 ActiveRecord 链接查询。请参阅http://edgerails.info/articles/what-s-new-in-edge-rails/2010/02/23/the-skinny-on-scopes-forming-named-scope/索引.html。
索引
其次,如果您无论如何都要执行所有这些查询,请确保对数据库进行索引,以便例如通过名称快速查找
状态
。完成第一个索引的示例迁移:会话
如果您需要的数据并不重要,即您不需要依赖它来进一步计算或数据库更新,您可以考虑将其中一些数据存储在用户的会话中。如果这样做,您将来可以简单地从会话中读取所需的任何内容,而不必在每次页面加载时访问数据库。
如果此数据很关键和/或必须更新到第二个,则避免此选项。
计数器缓存
如果您需要定期进行某些记录计数,请考虑设置
counter_cache
。基本上,在您的模型中,您需要执行以下操作:确保您的
parent
表有一个名为child_count
的字段,Rails 将在每个子项创建/删除时为您更新此字段。如果您使用 counter_caching,您将避免访问数据库来获取计数。注意:使用 counter_caching 将导致创建和销毁操作稍长,但如果您经常使用这些计数,通常值得使用 counter_cache。
Scopes
First off, you should move many of these into
scopes
, which will allow you to use them in far more flexible ways, such as chaining queries using ActiveRecord. See http://edgerails.info/articles/what-s-new-in-edge-rails/2010/02/23/the-skinny-on-scopes-formerly-named-scope/index.html.Indexes
Second, if you're doing all these queries anyway, make sure you index your database to, for example, find
Status
quickly by name. A sample migration to accomplish the first index:Session
If the data you need here is not critical, i.e. you don't need to rely on it to further calculations or database updates, you could consider storing some of this data in the user's session. If you do so, you can simply read whatever you need from the session in the future instead of hitting your db on every page load.
If this data is critical and/or it must be updated to the second, then avoid this option.
Counter Caching
If you need certain record counts on a regular basis, consider setting up a
counter_cache
. Basically, in your models, you do the following:Ensure your
parent
table has a field calledchild_count
and Rails will update this field for you on every child's creation/deletion. If you use counter_caching, you will avoid hitting the database to get the counts.Note: Using counter_caching will result in a slightly longer create and destroy action, but if you are using these counts often, it's usually worth going with counter_cache.
为此,您应该只需要 1 个数据库查询,例如:
然后使用 Enumerable#group_by 将帖子收集到不同的类别中:
这将为您提供哈希值:
等等。
You should only need 1 database query for this, something like:
Then use Enumerable#group_by to collect the posts into the different categories:
which will give you a hash:
etc.