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}
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
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With