将模块扩展到模型会导致ArgumentError“xx的副本已从模块树中删除但仍处于活动状态”

时间:2014-02-19 10:36:23

标签: ruby-on-rails ruby

如何将模块扩展到模型类并使用自定义类的实例作为模型的类实例变量,以便在下一个请求到来时,可以找到自定义类并删除旧实例?

这适用于生产模式或将config.cache_classes设置为true时。以下是这个想法:

/lib/base_sample/load_samples.rb

module BaseSample
  module LoadSamples
    attr_accessor :samples

    def load_samples
      @samples ||= Samples.new
      # ..some work
      @samples
    end
  end
end

/lib/base_sample/samples.rb

module BaseSample
  class Samples
    ...
  end
end

我将LoadSamples延伸到ActiveRecord::Base

/config/initializers/extensions.rb

ActiveRecord::Base.extend BaseSample::LoadSamples

/app/models/user.rb

class User < ActiveRecord::Base
  load_samples
end

第一页正确加载,但后续请求会出现以下错误:

ArgumentError in UsersController#new

A copy of BaseSample::LoadSamples has been removed from the module tree but is still active!

并指向行:

@samples ||= Samples.new

完整Stacktrace

/home/harsh/Documents/works/rails/v238/grp_validations_yml/vendor/ruby/1.8/gems/activesupport-2.3.8/lib/active_support/dependencies.rb:414:in `load_missing_constant'
/home/harsh/Documents/works/rails/v238/grp_validations_yml/vendor/ruby/1.8/gems/activesupport-2.3.8/lib/active_support/dependencies.rb:80:in `rake_original_const_missing'
/home/harsh/Documents/works/rails/v238/grp_validations_yml/vendor/ruby/1.8/gems/rake-0.9.2.2/lib/rake/ext/module.rb:36:in `const_missing'
/home/harsh/Documents/works/rails/v238/grp_validations_yml/lib/base_sample/load_samples.rb:10:in `load_validation_rules_from_file'
/home/harsh/Documents/works/rails/v238/grp_validations_yml/app/models/user.rb:2
/home/harsh/Documents/works/rails/v238/grp_validations_yml/vendor/ruby/1.8/gems/activesupport-2.3.8/lib/active_support/dependencies.rb:380:in `load_without_new_constant_marking'
/home/harsh/Documents/works/rails/v238/grp_validations_yml/vendor/ruby/1.8/gems/activesupport-2.3.8/lib/active_support/dependencies.rb:380:in `load_file'
/home/harsh/Documents/works/rails/v238/grp_validations_yml/vendor/ruby/1.8/gems/activesupport-2.3.8/lib/active_support/dependencies.rb:521:in `new_constants_in'
/home/harsh/Documents/works/rails/v238/grp_validations_yml/vendor/ruby/1.8/gems/activesupport-2.3.8/lib/active_support/dependencies.rb:379:in `load_file'
/home/harsh/Documents/works/rails/v238/grp_validations_yml/vendor/ruby/1.8/gems/activesupport-2.3.8/lib/active_support/dependencies.rb:259:in `require_or_load'
/home/harsh/Documents/works/rails/v238/grp_validations_yml/vendor/ruby/1.8/gems/activesupport-2.3.8/lib/active_support/dependencies.rb:425:in `load_missing_constant'
/home/harsh/Documents/works/rails/v238/grp_validations_yml/vendor/ruby/1.8/gems/activesupport-2.3.8/lib/active_support/dependencies.rb:80:in `rake_original_const_missing'
/home/harsh/Documents/works/rails/v238/grp_validations_yml/vendor/ruby/1.8/gems/rake-0.9.2.2/lib/rake/ext/module.rb:36:in `const_missing'
/home/harsh/Documents/works/rails/v238/grp_validations_yml/vendor/ruby/1.8/gems/activesupport-2.3.8/lib/active_support/dependencies.rb:92:in `const_missing'
/home/harsh/Documents/works/rails/v238/grp_validations_yml/vendor/ruby/1.8/gems/activesupport-2.3.8/lib/active_support/dependencies.rb:437:in `load_missing_constant'
/home/harsh/Documents/works/rails/v238/grp_validations_yml/vendor/ruby/1.8/gems/activesupport-2.3.8/lib/active_support/dependencies.rb:96:in `const_missing'
/home/harsh/Documents/works/rails/v238/grp_validations_yml/app/controllers/users_controller.rb:27:in `new'
/home/harsh/Documents/works/rails/v238/grp_validations_yml/vendor/ruby/1.8/gems/actionpack-2.3.8/lib/action_controller/base.rb:1331:in `send'
/home/harsh/Documents/works/rails/v238/grp_validations_yml/vendor/ruby/1.8/gems/actionpack-2.3.8/lib/action_controller/base.rb:1331:in `perform_action_without_filters'
/home/harsh/Documents/works/rails/v238/grp_validations_yml/vendor/ruby/1.8/gems/actionpack-2.3.8/lib/action_controller/filters.rb:617:in `call_filters'
/home/harsh/Documents/works/rails/v238/grp_validations_yml/vendor/ruby/1.8/gems/actionpack-2.3.8/lib/action_controller/filters.rb:610:in `perform_action_without_benchmark'
/home/harsh/Documents/works/rails/v238/grp_validations_yml/vendor/ruby/1.8/gems/actionpack-2.3.8/lib/action_controller/benchmarking.rb:68:in `perform_action_without_rescue'
/home/harsh/Documents/works/rails/v238/grp_validations_yml/vendor/ruby/1.8/gems/activesupport-2.3.8/lib/active_support/core_ext/benchmark.rb:17:in `ms'
/home/harsh/.rbenv/versions/1.8.7-p374/lib/ruby/1.8/benchmark.rb:308:in `realtime'
/home/harsh/Documents/works/rails/v238/grp_validations_yml/vendor/ruby/1.8/gems/activesupport-2.3.8/lib/active_support/core_ext/benchmark.rb:17:in `ms'
/home/harsh/Documents/works/rails/v238/grp_validations_yml/vendor/ruby/1.8/gems/actionpack-2.3.8/lib/action_controller/benchmarking.rb:68:in `perform_action_without_rescue'
/home/harsh/Documents/works/rails/v238/grp_validations_yml/vendor/ruby/1.8/gems/actionpack-2.3.8/lib/action_controller/rescue.rb:160:in `perform_action_without_flash'
/home/harsh/Documents/works/rails/v238/grp_validations_yml/vendor/ruby/1.8/gems/actionpack-2.3.8/lib/action_controller/flash.rb:151:in `perform_action'
/home/harsh/Documents/works/rails/v238/grp_validations_yml/vendor/ruby/1.8/gems/actionpack-2.3.8/lib/action_controller/base.rb:532:in `send'
/home/harsh/Documents/works/rails/v238/grp_validations_yml/vendor/ruby/1.8/gems/actionpack-2.3.8/lib/action_controller/base.rb:532:in `process_without_filters'
/home/harsh/Documents/works/rails/v238/grp_validations_yml/vendor/ruby/1.8/gems/actionpack-2.3.8/lib/action_controller/filters.rb:606:in `process'
/home/harsh/Documents/works/rails/v238/grp_validations_yml/vendor/ruby/1.8/gems/actionpack-2.3.8/lib/action_controller/base.rb:391:in `process'
/home/harsh/Documents/works/rails/v238/grp_validations_yml/vendor/ruby/1.8/gems/actionpack-2.3.8/lib/action_controller/base.rb:386:in `call'
/home/harsh/Documents/works/rails/v238/grp_validations_yml/vendor/ruby/1.8/gems/actionpack-2.3.8/lib/action_controller/routing/route_set.rb:438:in `call'
/home/harsh/Documents/works/rails/v238/grp_validations_yml/vendor/ruby/1.8/gems/actionpack-2.3.8/lib/action_controller/dispatcher.rb:87:in `dispatch'
/home/harsh/Documents/works/rails/v238/grp_validations_yml/vendor/ruby/1.8/gems/actionpack-2.3.8/lib/action_controller/dispatcher.rb:121:in `_call'
/home/harsh/Documents/works/rails/v238/grp_validations_yml/vendor/ruby/1.8/gems/actionpack-2.3.8/lib/action_controller/dispatcher.rb:130:in `build_middleware_stack'
/home/harsh/Documents/works/rails/v238/grp_validations_yml/vendor/ruby/1.8/gems/activerecord-2.3.8/lib/active_record/query_cache.rb:29:in `call'
/home/harsh/Documents/works/rails/v238/grp_validations_yml/vendor/ruby/1.8/gems/activerecord-2.3.8/lib/active_record/query_cache.rb:29:in `call'
/home/harsh/Documents/works/rails/v238/grp_validations_yml/vendor/ruby/1.8/gems/activerecord-2.3.8/lib/active_record/connection_adapters/abstract/query_cache.rb:34:in `cache'
/home/harsh/Documents/works/rails/v238/grp_validations_yml/vendor/ruby/1.8/gems/activerecord-2.3.8/lib/active_record/query_cache.rb:9:in `cache'
/home/harsh/Documents/works/rails/v238/grp_validations_yml/vendor/ruby/1.8/gems/activerecord-2.3.8/lib/active_record/query_cache.rb:28:in `call'
/home/harsh/Documents/works/rails/v238/grp_validations_yml/vendor/ruby/1.8/gems/activerecord-2.3.8/lib/active_record/connection_adapters/abstract/connection_pool.rb:361:in `call'
/home/harsh/Documents/works/rails/v238/grp_validations_yml/vendor/ruby/1.8/gems/actionpack-2.3.8/lib/action_controller/string_coercion.rb:25:in `call'
/home/harsh/Documents/works/rails/v238/grp_validations_yml/vendor/ruby/1.8/gems/rack-1.1.6/lib/rack/head.rb:9:in `call'
/home/harsh/Documents/works/rails/v238/grp_validations_yml/vendor/ruby/1.8/gems/rack-1.1.6/lib/rack/methodoverride.rb:24:in `call'
/home/harsh/Documents/works/rails/v238/grp_validations_yml/vendor/ruby/1.8/gems/actionpack-2.3.8/lib/action_controller/params_parser.rb:15:in `call'
/home/harsh/Documents/works/rails/v238/grp_validations_yml/vendor/ruby/1.8/gems/actionpack-2.3.8/lib/action_controller/session/cookie_store.rb:99:in `call'
/home/harsh/Documents/works/rails/v238/grp_validations_yml/vendor/ruby/1.8/gems/actionpack-2.3.8/lib/action_controller/failsafe.rb:26:in `call'
/home/harsh/Documents/works/rails/v238/grp_validations_yml/vendor/ruby/1.8/gems/rack-1.1.6/lib/rack/lock.rb:11:in `call'
/home/harsh/Documents/works/rails/v238/grp_validations_yml/vendor/ruby/1.8/gems/rack-1.1.6/lib/rack/lock.rb:11:in `synchronize'
/home/harsh/Documents/works/rails/v238/grp_validations_yml/vendor/ruby/1.8/gems/rack-1.1.6/lib/rack/lock.rb:11:in `call'
/home/harsh/Documents/works/rails/v238/grp_validations_yml/vendor/ruby/1.8/gems/actionpack-2.3.8/lib/action_controller/dispatcher.rb:114:in `call'
/home/harsh/Documents/works/rails/v238/grp_validations_yml/vendor/ruby/1.8/gems/actionpack-2.3.8/lib/action_controller/reloader.rb:34:in `run'
/home/harsh/Documents/works/rails/v238/grp_validations_yml/vendor/ruby/1.8/gems/actionpack-2.3.8/lib/action_controller/dispatcher.rb:108:in `call'
/home/harsh/Documents/works/rails/v238/grp_validations_yml/vendor/ruby/1.8/gems/rails-2.3.8/lib/rails/rack/static.rb:31:in `call'
/home/harsh/Documents/works/rails/v238/grp_validations_yml/vendor/ruby/1.8/gems/rack-1.1.6/lib/rack/urlmap.rb:47:in `call'
/home/harsh/Documents/works/rails/v238/grp_validations_yml/vendor/ruby/1.8/gems/rack-1.1.6/lib/rack/urlmap.rb:41:in `each'
/home/harsh/Documents/works/rails/v238/grp_validations_yml/vendor/ruby/1.8/gems/rack-1.1.6/lib/rack/urlmap.rb:41:in `call'
/home/harsh/Documents/works/rails/v238/grp_validations_yml/vendor/ruby/1.8/gems/rails-2.3.8/lib/rails/rack/log_tailer.rb:17:in `call'
/home/harsh/Documents/works/rails/v238/grp_validations_yml/vendor/ruby/1.8/gems/rack-1.1.6/lib/rack/content_length.rb:13:in `call'
/home/harsh/Documents/works/rails/v238/grp_validations_yml/vendor/ruby/1.8/gems/rack-1.1.6/lib/rack/handler/webrick.rb:48:in `service'
/home/harsh/.rbenv/versions/1.8.7-p374/lib/ruby/1.8/webrick/httpserver.rb:104:in `service'
/home/harsh/.rbenv/versions/1.8.7-p374/lib/ruby/1.8/webrick/httpserver.rb:65:in `run'
/home/harsh/.rbenv/versions/1.8.7-p374/lib/ruby/1.8/webrick/server.rb:173:in `start_thread'
/home/harsh/.rbenv/versions/1.8.7-p374/lib/ruby/1.8/webrick/server.rb:162:in `start'
/home/harsh/.rbenv/versions/1.8.7-p374/lib/ruby/1.8/webrick/server.rb:162:in `start_thread'
/home/harsh/.rbenv/versions/1.8.7-p374/lib/ruby/1.8/webrick/server.rb:95:in `start'
/home/harsh/.rbenv/versions/1.8.7-p374/lib/ruby/1.8/webrick/server.rb:92:in `each'
/home/harsh/.rbenv/versions/1.8.7-p374/lib/ruby/1.8/webrick/server.rb:92:in `start'
/home/harsh/.rbenv/versions/1.8.7-p374/lib/ruby/1.8/webrick/server.rb:23:in `start'
/home/harsh/.rbenv/versions/1.8.7-p374/lib/ruby/1.8/webrick/server.rb:82:in `start'
/home/harsh/Documents/works/rails/v238/grp_validations_yml/vendor/ruby/1.8/gems/rack-1.1.6/lib/rack/handler/webrick.rb:14:in `run'
/home/harsh/Documents/works/rails/v238/grp_validations_yml/vendor/ruby/1.8/gems/rails-2.3.8/lib/commands/server.rb:111
script/server:3:in `require'
script/server:3

有关如何改进这一点的任何输入,以便我可以在开发模式下处理它?<​​/ p>

我使用的是Rails 2.3.8。

编辑:嗯,我深入挖掘ActiveSupport::Dependencies,经过几个小时的调试后发现Object找不到名为BaseSamples::LoadSamples的常量。我删除了文件extensions.rb,基本上删除了我扩展ActiveRecord::Base和直接扩展User模型的行。这样就有用了。

任何人都可以解释为什么LoadSamples第一次正确加载而不是第二次加载?

0 个答案:

没有答案