Mystifying "undefined constant" issue with Ruby/Rails
Asked Answered
T

1

13

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*

Turkestan answered 16/7, 2011 at 22:32 Comment(3)
I'd say your edit qualifies as an answer. You're allowed to answer your own question and I doubt anyone would object to an answer to something tricky like that.Blumenfeld
@Turkestan Glad you were able to work out the issue.Keene
Agree with mu. Please add your solution as an answer to your question, and mark it best answer. Answering your own questions is definitely allowed :)Slug
T
3

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.

Turkestan answered 26/7, 2011 at 3:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.