Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

In a Rails 3.2 app I need to access url_helpers in a lib file. I'm using

Rails.application.routes.url_helpers.model_url(model) 

but I'm getting

ArgumentError (Missing host to link to! Please provide the :host parameter, set default_url_options[:host], or set :only_path to true): 

I've found a few things written about this, but nothing that really explains how to solve this for multiple environments.

i.e. I assume I need to add something to my development.rb and production.rb files, but what?

Closest I've seen to an answer suggested using config.action_mailer.default_url_option, but this does not work outside of action mailer.

What is the correct way to set the host for multiple environments?

like image 711
Andy Harvey Avatar asked May 23 '13 17:05

Andy Harvey


2 Answers

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.

And now thanks to this great blog post 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!

like image 76
Andy Harvey Avatar answered Sep 23 '22 15:09

Andy Harvey


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

like image 43
bbozo Avatar answered Sep 19 '22 15:09

bbozo