Rails routing outside views and controllers
We use Rails routing helpers in views and controllers but sometimes we need to generate a link from a service class or background job.
To get started, let’s assume that we have a post resources which provide us with this path helper:
posts_path # "/posts"
We add the following simple service class:
class MyService
include Rails.application.routes.url_helpers
def generate_stuff
posts_path
end
end
To check the link generation, we can use Rails console:
MyService.new.generate_stuff # "/posts"
I noticed in different projects that I need to use the URL helper instead of path helper. So we will edit the service as follows:
class MyService
include Rails.application.routes.url_helpers
def generate_stuff
posts_url
end
end
But we will get the following Error:
Missing host to link to! Please provide the :host parameter,set default_url_options[:host], or set :only_path to true
To fix it we need just to add a config for existing environments in our applications for example:
# development
# config/environments/development.rb
Rails.application.routes.default_url_options[:host] = 'localhost:3000'
# production
# config/environments/production.rb
Rails.application.routes.default_url_options[:host] = 'mysite.com'
You may say, that we don’t need this configuration when using URL helpers in views, right?
Absolutely, from Rails documentation for UrlFor method we can check:
By default, all controllers and views have access to a special version
of #url_for, that already knows what the current hostname is.
So if you use #url_for in your controllers or your views,
then you don’t need to explicitly pass the :host argument.
That’s it, have fun and keep coding 🙂