代码之家  ›  专栏  ›  技术社区  ›  holden

带货币宝石的rails缓存(欧盟中央银行)

  •  1
  • holden  · 技术社区  · 14 年前

    http://github.com/RubyMoney/eu_central_bank

    eu_bank ||= EuCentralBank.new
    eu_bank.update_rates
    #Rails.cache.fetch('rates', :expires_in => 24.hours) { eu_bank.update_rates }
    rate = eu_bank.exchange_with(Money.new(100, session[:currency]), "USD").to_f
    

    它有一个功能,可以将费率写入某个文件。。。但我也不确定这是我想要的。我也在使用heroku,它有一个只读文件系统。

    eu_bank.save_rates("/some/file/location/exchange_rates.xml")
    

    4 回复  |  直到 14 年前
        1
  •  4
  •   Peter Sorowka    10 年前

    这可以通过使用Rails低级缓存和before_过滤器来实现:

    class ApplicationController < ActionController::Base
    
      before_filter :set_conversion_rates
    
      def set_conversion_rates
    
        rates = Rails.cache.fetch "money:eu_central_bank_rates", expires_in: 24.hours do
    
          Money.default_bank.save_rates_to_s
        end
    
        Money.default_bank.update_rates_from_s rates
    
      end
    end
    

    此代码将在24小时内下载一次费率,并将结果保存到缓存(无论您使用何种缓存模块),在每次请求时,bank对象都会从缓存中加载费率。

        2
  •  1
  •   lacco    12 年前

    https://github.com/RubyMoney/eu_central_bank/commit/fc6c4a3164ad47747c8abbf5c21df617d2d9e644 是必需的。因为我不想每24小时重新启动我的web进程,所以我在 before_filter (可能更好的方式?)。实际的 Money.default_bank.update_rates 调用可能会移动到重复的resque作业(或其他)。

    module MyNamespace
      class Bank
        def self.update_rates_if_changed
          if last_updated.nil? || last_updated + 12.hours <= Time.now
            update_rates
          end
        end
    
        def self.update_rates
          fetch_rates
    
          # Take latest available currency rates snapshot
          [0, 1, 2].each do |days|
            date = Date.today - days.days
            next unless Rails.cache.exist?(rate_key(date))
    
            begin
              rates = Rails.cache.read(rate_key(date))
              Money.default_bank.update_rates_from_s(rates)
            rescue Nokogiri::XML::SyntaxError
              print "error occurred while reading currency rates"
              # our rates seem to be invalid, so clear the cache and retry
              Rails.cache.delete(rate_key(date))
              update_rates
            end
    
            break
          end
        end
    
        private
        def self.fetch_rates
          return if Rails.cache.exist?(rate_key)
    
          print "Updating currency rates ... "
          begin
            Rails.cache.write(rate_key, Money.default_bank.save_rates_to_s)
            puts "finished"
          rescue Exception => ex
            puts "error occurred: #{ex.inspect}"
          end
        end
    
        def self.rate_key(date = Date.today)
          ["exchange_rates", date.strftime("%Y%m%d")]
        end
    
        def self.last_updated
          Money.default_bank.last_updated
        end
      end
    end
    

    应用程序/控制器/应用程序控制器.rb

    class ApplicationController
      before_filter :check_for_currency_updates
    
      def check_for_currency_updates
        MyNamespace::Bank.update_rates_if_changed
      end
    end
    

    配置/初始化器/money.rb

    MyNamespace::Bank.update_rates_if_changed
    
        3
  •  0
  •   hellvinz    14 年前

    Since the amount of data is relatively small you can Marshal.dump eu_bank对象,将其存储在memchache中,有效期为24小时(请参见 this doc ).

    每次你需要它的时候,你都会从memchache和Marshal中检索到它并加载它。

    如果密钥已过期或已从缓存中消失,则将其重新获取

        4
  •  0
  •   Laurynas    13 年前

    配置/初始化器/money.rb

    # Money exchange
    ::Money.default_bank = ::EuCentralBank.new
    
    EU_CENTRAL_BANK_CACHE = '/tmp/eu_bank_exchange_rates.xml'
    
    # Right now we update exchange rates on app restart. App is restarted daily after logs rotation,
    # Should be ok for now.
    
    if (!File.exist?(EU_CENTRAL_BANK_CACHE)) || File.mtime(EU_CENTRAL_BANK_CACHE) < 23.hours.ago
      p "Updating money exchange rates"
      ::Money.default_bank.save_rates(EU_CENTRAL_BANK_CACHE)
    end
    
    ::Money.default_bank.update_rates(EU_CENTRAL_BANK_CACHE)