导轨上的红宝石 - 清理控制器以加快应用程序速度



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

目前在我的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 )

..这真的只是一小块,我至少有两倍的类似电话。问题是我几乎每页上都需要这些数字,但我觉得我在这里对 DB wayyyy 的次数太多了。

有什么更好的实施想法吗?

作用域

首先,您应该将其中许多移动到 scopes 中,这将允许您以更灵活的方式使用它们,例如使用 ActiveRecord 链接查询。请参阅 http://edgerails.info/articles/what-s-new-in-edge-rails/2010/02/23/the-skinny-on-scopes-formerly-named-scope/index.html。

指标

其次,如果您无论如何都要执行所有这些查询,请确保为数据库编制索引,例如,按名称快速查找Status。完成第一个索引的示例迁移:

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。

为此,您应该只需要 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' => [...]}

等。

相关内容

  • 没有找到相关文章

最新更新