How to use url helpers in lib modules, and set host for multiple environments

This is a problem that I keep running into and has bugged me for a while.

I know many will say it goes against the MVC architecture to access url_helpers in models and modules, but there are times—such as when interfacing with an external API—where it does make sense.

After much searching I've found an answer!

#lib/routing.rb

module Routing
  extend ActiveSupport::Concern
  include Rails.application.routes.url_helpers

  included do
    def default_url_options
      ActionMailer::Base.default_url_options
    end
  end
end

#lib/url_generator.rb

class UrlGenerator
  include Routing
end

I can now call the following in any model, module, class, console, etc

UrlGenerator.new.models_url

Result!


A slight improvement (at least for me) on Andy's lovely answer

module UrlHelpers

  extend ActiveSupport::Concern

  class Base
    include Rails.application.routes.url_helpers

    def default_url_options
      ActionMailer::Base.default_url_options
    end
  end

  def url_helpers
    @url_helpers ||= UrlHelpers::Base.new
  end

  def self.method_missing method, *args, &block
    @url_helpers ||= UrlHelpers::Base.new

    if @url_helpers.respond_to?(method)
      @url_helpers.send(method, *args, &block)
    else
      super method, *args, &block
    end
  end

end

and the way you use it is:

include UrlHelpers
url_helpers.posts_url # returns https://blabla.com/posts

or simply

UrlHelpers.posts_url # returns https://blabla.com/posts

Thank you Andy! +1