清理控制器以加速应用程序

发布于 2024-11-08 17:38:10 字数 927 浏览 0 评论 0原文

因此,在我的应用程序中,我有在整体布局中使用的通知和不同的记录计数,因此每个页面都需要它们。

目前在我的 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

不羁少年 2024-11-15 17:38:10

首先,您应该将其中的许多内容

移至范围中,这将允许您以更灵活的方式使用它们,例如使用 ActiveRecord 链接查询。请参阅http://edgerails.info/articles/what-s-new-in-edge-rails/2010/02/23/the-skinny-on-scopes-forming-named-scope/索引.html

索引

其次,如果您无论如何都要执行所有这些查询,请确保对数据库进行索引,以便例如通过名称快速查找状态。完成第一个索引的示例迁移:

add_index :status (or the name of your Status controller), :name

会话

如果您需要的数据并不重要,即您不需要依赖它来进一步计算或数据库更新,您可以考虑将其中一些数据存储在用户的会话中。如果这样做,您将来可以简单地从会话中读取所需的任何内容,而不必在每次页面加载时访问数据库。

如果此数据很关键和/或必须更新到第二个,则避免此选项。

计数器缓存

如果您需要定期进行某些记录计数,请考虑设置 counter_cache。基本上,在您的模型中,您需要执行以下操作:

Parent.rb
has_many :children

Child.rb
belongs_to :parent, :counter_cache => true

确保您的 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:

add_index :status (or the name of your Status controller), :name

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:

Parent.rb
has_many :children

Child.rb
belongs_to :parent, :counter_cache => true

Ensure your parent table has a field called child_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.

征棹 2024-11-15 17:38:10

为此,您应该只需要 1 个数据库查询,例如:

@posts = Post.where(:user_id => current_user.id).includes(:status)

然后使用 Enumerable#group_by 将帖子收集到不同的类别中:

posts_by_status = @posts.group_by do {|post| post.status.name }

这将为您提供哈希值:

{'Alive' => [...], 'Dead' => [...]}

等等。

You should only need 1 database query for this, something like:

@posts = Post.where(:user_id => current_user.id).includes(:status)

Then use Enumerable#group_by to collect the posts into the different categories:

posts_by_status = @posts.group_by do {|post| post.status.name }

which will give you a hash:

{'Alive' => [...], 'Dead' => [...]}

etc.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文