3

我们使用 Rails.cache 并在加载调用类 X 的页面时看到未定义的类/模块 X 错误。我们按照此处的建议包含一个初始化程序,该初始化程序需要开发环境中的所有模型。

但是,我们看到了同样的错误。还有其他建议吗?我们在下面包含了初始化程序代码,从输出到控制台,看起来代码正在被调用。

我们在 Rails 3.2.12 + Ruby 1.9.3 上。

if Rails.env == "development"
  Dir.foreach("#{Rails.root}/app/models") do |model_name|
    puts "REQUIRING DEPENDENCY: #{model_name}"
    require_dependency model_name unless model_name == "." || model_name == ".."    
  end 
end

堆栈跟踪:

Processing by DandyController#get_apps as JSON
  Parameters: {"category"=>"featured", "country_id"=>"143441", "language_id"=>"EN"}
WARNING: Can't verify CSRF token authenticity
Completed 500 Internal Server Error in 2ms

ArgumentError (undefined class/module App):
  app/controllers/dandy_controller.rb:66:in `get_featured_apps'
  app/controllers/dandy_controller.rb:50:in `get_apps'


      Rendered C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/actionpack-3.2.12/lib/action_dispatch/middleware/templat
    es/rescues/_trace.erb (2.0ms)
      Rendered C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/actionpack-3.2.12/lib/action_dispatch/middleware/templat
    es/rescues/_request_and_response.erb (2.0ms)
      Rendered C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/actionpack-3.2.12/lib/action_dispatch/middleware/templat
    es/rescues/diagnostics.erb within rescues/layout (46.0ms)

代码:

def get_featured_apps( country_id )
    # Fetch featured apps from cache or from DB
    apps = Rails.cache.fetch( 'featured_apps', {:expires_in => 1.days} ) do
        logger.info '+++ Cache miss: featured apps'
        get_featured_apps_helper country_id     
    end

    # Get sponsored results



    apps = get_featured_apps_helper country_id
    # Return featured apps
    return apps
end
4

2 回答 2

3

我已经覆盖了 fetch 方法,它为我创造了奇迹!

unless Rails.env.production?
  module ActiveSupport
    module Cache
      class Store
        def fetch(name, options = nil)
          if block_given?
            yield
          end
        end
      end
    end
  end
end
于 2014-11-28T18:12:01.370 回答
0

一个更优雅的解决方案是编写一个包装器方法,您可以在调用时调用Rails.cache.fetch

def some_func
  apps = with_autoload_of(App) do
    Rails.cache.fetch( 'featured_apps', {:expires_in => 1.days} ) do
      logger.info '+++ Cache miss: featured apps'
      get_featured_apps_helper country_id
    end     
  end
end

##
# A simple wrapper around a block that requires the provided class to be
# auto-loaded prior to execution.
#
# This method must be passed a block, which it always yields to.
#
# This is typically used to wrap `Rails.cache.fetch` calls to ensure that
# the autoloader has loaded any class that's about to be referenced.
#
# @param [Class] clazz
#   The class to ensure gets autoloaded.
#
def self.with_autoload_of(clazz)
  yield
end
于 2016-03-24T18:15:12.497 回答