I've got a Rails project where a constant is being nuked at some point while serving a request.
I'm using the mime/types
and restclient
gems. The restclient
module defines an extension to MIME
which contains the method type_for_extension
.
module RestClient
...
def stringify_headers headers
result[key] = target_values.map { |ext| MIME::Types.type_for_extension(ext.to_s.strip) }.join(', ')
...
end
end
end
module MIME
class Types
def type_for_extension ext
candidates = @extension_index[ext]
candidates.empty? ? ext : candidates[0].content_type
end
class << self
def type_for_extension ext
@__types__.type_for_extension ext
end
end
end
end
I can access MIME::Types.type_for_extension
on my first invocation of a given controller action. On the second invocation, it's gone.
I can still use MIME::Types.type_for
, but the added method is simply gone, so when I try to use the RestClient module it throws an exception on the line showin in stringify_headers
:
NoMethodError, message: undefined method `type_for_extension' for MIME::Types:Class
**How is this possible? type_for_extension
defined in the same file as stringify_headers
; how could the latter get nuked but not the former?
EDIT: FIXED IT!
In my config:
config.gem "aws-s3", :version => ">= 0.6.2", :lib => "aws/s3"
config.gem 'mime-types', :lib => 'mime/types'
aws-s3
was loading mime-types
via require_library_or_gem
, which ultimate invoked ActiveSupport::Dependencies.autoload_module!
which maintains a table called autoloaded_constants
which are nuked when 开发者_开发问答ActionController.close
calls Dispatcher.cleanup_application
.
Fix was to load mime-types
first, so it's not autoloaded.
*whew*
Answering my own question by request.
In my config:
config.gem "aws-s3", :version => ">= 0.6.2", :lib => "aws/s3"
config.gem 'mime-types', :lib => 'mime/types'
aws-s3
library was loading mime-types
via require_library_or_gem
, which ultimately invoked ActiveSupport::Dependencies.autoload_module!
which maintains a table called autoloaded_constants
which are nuked when ActionController.close
calls Dispatcher.cleanup_application.
Fix was to load mime-types first, so it's not autoloaded.
精彩评论