尽管在初始化程序中需要模型,但Rails 3中的未定义类/模块X.

时间:2013-03-21 01:15:56

标签: ruby-on-rails ruby-on-rails-3

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

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

我们使用的是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

2 个答案:

答案 0 :(得分:3)

我已经覆盖了为我创造奇迹的抓取方法!

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

答案 1 :(得分: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