Search code examples
ruby-on-railsrubyclassclass-extensions

Ruby class extension in Rails works when declared locally, returns `nil` when imported from `/lib/`


TLDR: A hash extension works flawlessly, returning the desired output, when included locally in my Mailer, but always returns nil when imported from a module in lib/, even though the class method is successfully loaded.

When I declare the extension in my mailer.rb file, before my class definition, as in:

class Hash
  def try_deep(*fields)
    ...
  end
end

class MyMailer < ApplicationMailer
  some_hash.try_deep(:some_key)
end

it works flawlessly, but this is bad practice. I thought it better to declare the extension in /lib/core_ext/hash/try_deep.rb and then require it in the Mailer, as in:

/lib/core_ext/hash/try_deep.rb:

module CoreExtensions
  module Hash
    module TryDeep
      def try_deep(*fields)
        ...
      end
    end
  end
end

/my_mailer.rb:

require 'core_ext/hash/try_deep'

class MyMailer < ApplicationMailer
  Hash.include CoreExtensions::Hash::TryDeep
  some_hash.try_deep(:some_key)
end

Solution

  • You need to inject your custom method into Hash outside of your class:

    my_mailer.rb:

    require 'core_ext/hash/try_deep'
    
    class Hash
      include CoreExtensions::Hash::TryDeep
    end
    
    class MyMailer < ApplicationMailer
      some_hash.try_deep(:some_key)
    end