开发者

Load a collection once from db, use throughout site

开发者 https://www.devze.com 2023-02-15 03:54 出处:网络
I want to load a collection only once from the db so I don\'t need to do it on each request or store it in cache.

I want to load a collection only once from the db so I don't need to do it on each request or store it in cache.

Where can I do this in Rails 3? At one point in the application start cycle?

Al开发者_运维百科so, how will this collection be made available through the site?


It might be simple enough to have a cached class method. This sort of thing comes in handy for the contents of drop-down lists which changes so infrequently it's as good as static:

class Country
  def self.cached_list
    @cached_list ||= self.all
  end
end

Keep in mind that class instance variables will persist for the life-span of the class itself. In the development environment this is one request, but in production this is all requests made to the same process.


In config/initializers/constants.rb,

you can do this:

SECTOR_NAMES = Sector.all.collect{|sector| sector.name}

and SECTOR_NAMES will be a constant available all throughout your app


You can store it in a class variable in one of your models.

class User < ActiveRecord::Base
  cattr_reader :special
  @@special = User.where(:special => true).all
  ...
end

It will be evaluated only during the startup of Rails if you have class caching enabled (and that is the default for production environment).


I use the following:

module ReferenceData
  def self.included(model)
    model.instance_eval do
      def self.find_by_sql(*args)
        sql = args.first
        ReferenceDataCache.get(sql) || ReferenceDataCache.put(sql, super)
      end
    end
  end
end

class ReferenceDataCache
  @@cache = {}
  def self.find_by_sql(*args)
    sql = args.first
    ReferenceDataCache.get(sql) || ReferenceDataCache.put(sql, super)
  end

  def self.put(sql, obj)
    Rails.logger.info "[Caching Reference Data Query] #{sql}"
    @@cache[sql] = obj unless obj.empty?
    return obj
  end

  def self.get(sql)
    if @@cache.has_key?(sql)
      return @@cache[sql]
    end
    nil
  end
end

You can then make any class a reference data class by doing:

class Cities < AR:B
  include ReferenceData
end
0

精彩评论

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

关注公众号