Rails如何缓存ActiveRecord并保持代码干

时间:2017-03-22 14:00:23

标签: ruby-on-rails caching activerecord

我正在使用Ruby 2.1.7和Rails 4.0.2但我很高兴听到其他版本的解决方案。

我有一些数据库表,我想在HTTP请求之间缓存查询。我想完成一些事情:

  1. 我希望模型的使用能够无缝地感受到
  2. 我想尽可能少地覆盖默认行为
  3. 尽可能将代码保留为DRY
  4. 避免使用Poltergeist AntiPattern
  5. 有Lew-Level缓存: http://guides.rubyonrails.org/caching_with_rails.html#low-level-caching

    但是,如果我想缓存关联并保留关联名称以使接口可读,该怎么办?

    我可以想到3种方法,但似乎没有一种方法。

    class City < ActiveRecord::Base
      belongs_to :country
      attr_accessible :name,:country
    end
    
    class Country < ActiveRecord::Base
      has_many :cities
      attr_accessible :name,:cities
    
      # First Approach
      # Special method. does not override ActiveRecord. But does not work seamlessly
      def cached_cities
        Rails.cache.fetch("#{cache_key}/cities", expires_in: 12.hours) do
          cities.to_a
        end
      end
    
      # Second Approach
      # Using override. Feels seamlessly but Override the default ActiveRecord behavior
      def cities
        Rails.cache.fetch("#{cache_key}/cities", expires_in: 12.hours) do
          City.where({country: self}).to_a
        end
      end
    end
    
    # Third Approach
    # I think it is a bit Poltergeist anti-pattern
    class CachedCountry
      attr_accessor :cities
    
      def initialize(country)
        self.cities = Rails.cache.fetch("#{country.cache_key}/cities", expires_in: 12.hours) do
          cities.to_a
        end
      end
    
    end
    
    class CitiesController < BackendController
      def get_usa_cities
        render json: Country.find('USA').cached_cities.first
        # Other way
        render json: Country.find('USA').cities.first
      end
    end
    

    我希望能够调用Country.find('USA')。cities并在HTTP请求之间缓存查询。但是城市属性也被定义为has_many关联。唯一的选择是做一些像Country.find('USA')。cached_cities?我更喜欢缓存将由默认的ActiveRecord行为

    封装

    以下是一些展示其中两种方法的链接:

    cached_cities - http://codebeerstartups.com/2014/11/scaling-ruby-on-rails-by-caching-your-database-queries/

    CachedCountry - https://robots.thoughtbot.com/activerecord-caching-and-the-single-responsibility

0 个答案:

没有答案