7

I have these two variables being set in the controller. How do I cache these so they don't communicate with the database each time, only the first time.

@tablenutrients = Nutrient.find(:all)
@columnnutrients = @tablenutrients.collect {|x| x.nutrient}
0

3 Answers 3

15

what @djlumley said.

In general, you can also configure and use ActiveSupport::Cache::Store to explicitly store your own custom variables. You could then get/set cached values, for example, like this:

@tablenutrients = Rails.cache.fetch("tablenutrients") do 
  Nutrient.find(:all)
end
Sign up to request clarification or add additional context in comments.

Comments

3

If your database is setup correctly, it should be caching your data by default. If you're using MySQL or postgresql you can change the amoutn of RAM the cache uses to ensure you're getting a high cache hit rate.

Beyond simple database caching, using something like Dalli to connect to memcached should make improving performance fairly easy.

Rails should take advantage of memcached to cache all your active record queries in memcached provided it's setup correctly. The Rails guide on caching together with the Dalli documentation should help you get started based on the version of Rails you're running.

Comments

3

Rails has a few built in caching options for you, two of which would likely work for you, depending on what you're doing with the query result:

Fragment Caching

If you were using this as a collection for a select box an often used form I would go with this option. This would allow you to cache not only the database result, but the actual HTML section of the page . This is done simply by throwing a <%= cache do %> around the section, like so:

<html>
   ...
   <body>
     ...
     <div class='content'>
       ...
       <%= cache do %>
         <%= select "nutrient", "nutrient", Nutrient.all.collect(&:nutrient) } %>
       <% end %>

Rail.cache

You could also write a method to talk directly to the built in cache store, by dropping a method in your ApplicationController and then have it run on a before_filter callback like so:

application_controller.rb

class ApplicationController < ActionController::Base
  before_filter :retrieve_nutrients

  def retrieve_nutrients
    @nutrients = Rails.cache.fetch("nutrients") do
      Nutrient.all.collect(&:nutrient)
    end
  end
end

In both cases in a production environment you're going to want to setup either Memcached or Redis to act as a caching layer (they sit behind Rails.cache and are a snap to implement). I would checkout Rails Guides for a deeper look at it.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.