开发者

Rails 3: Caching to Global Variable

I'm sure "global variable" will get the hair on the back of everyone's neck standing up. What I'm trying to do is store a hierarchical menu in an acts_as_tree data table (done). In application_helper.rb, I create an html menu by querying the database and walking the tree (done). I don't want to do this for every page load.

Here's what I tried:

application.rb

config.menu = nil

application_helper.rb

def my_menu_builder
  return MyApp::Application.config.menu if MyApp::Application.config.menu
  # All the menu building code that should only run once
  MyApp::Application.config.menu = menu_html
end

menu_controller.rb

def create
  # whatever create code
  expire_menu_cache
end

protected
def expire_menu_cache
  MyApp::Application.config.menu = nil
end

Where I stand right now is that on first page load, the database is, indeed, queried and the menu built. The results are stored in the config variable and the database is never again hit for this.

It's the cache expiration开发者_StackOverflow社区 part that's not working. When I reset the config.menu variable to nil, presumably the next time through my_menu_builder, it will detect that change and rebuild the menu, caching the new results. Doesn't seem to happen.

Questions:

Is Application.config a good place to store stuff like this? Does anyone see an obvious flaw in this caching strategy?

Don't say premature optimization -- that's the phase I'm in. The premature-optimization iteration :)

Thanks!


I would avoid global variables, and use Rails' caching facilities.

http://guides.rubyonrails.org/caching_with_rails.html


One way to achieve this is to set an empty hash in your application.rb file:

MY_VARS = {}

Then you can add whatever you want in this hash which is accessible everywhere.

MY_VARS[:foo] = "bar"

and elsewhere:

MY_VARS[:foo]

As you felt, this is not the Rails way to behave, even if it works. There are different ways to use caching in Rails:

  • simple cache in memory explained here:

    Rails.cache.read("city") # => nil

    Rails.cache.write("city", "Duckburgh")

    Rails.cache.read("city") # => "Duckburgh"

  • use of a real engine like memcached

I encourage you to have a look at http://railslab.newrelic.com/scaling-rails

This is THE place to learn caching in all it's shapes.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜