简体   繁体   中英

Cleaning up controllers to speed up application

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?

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 your database to, for example, find Status quickly by name. ,例如,按名称快速查找StatusA 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, ie 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.

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. 使用counter_caching会导致创建和销毁操作稍微延长,但如果您经常使用这些计数,则通常值得使用counter_cache。

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM