d11wtq
d11wtq

Reputation: 35318

Rails: Missing host to link to! Please provide :host parameter or set default_url_options[:host]

I have been googling for about 90 minutes now and still don't have an answer to this. Where do I set default_url_options? I've already set it for config.action_mailer.default_url_options to solve this same bug elsewhere, but now I'm getting this error when trying to use a URL helper inside an RSpec spec. I have no idea where it's expecting default_url_options to be set.

 Failure/Error: listing_url(listing).should match(/\/\d+-\w+$/)
 RuntimeError:
   Missing host to link to! Please provide :host parameter or set default_url_options[:host]
 # ./spec/routing/listing_routing_spec.rb:9:in `block (3 levels) in <top (required)>'

This code has nothing to do with emails/ActionMailer, it just happens to need a URL instead of a path.

Any ideas?

Upvotes: 243

Views: 151024

Answers (17)

mechnicov
mechnicov

Reputation: 15437

Rails.application.config.action_mailer.default_url_options

config.action_mailer.default_url_options = { host: 'my.domain', protocol: 'https', port: 356 }

Rails.application.default_url_options

self.default_url_options = config.action_mailer.default_url_options

Firstly setup Action Mailer default url options (like in the most of the answers)

And after that assign that options to Application. Initial question is exactly about this config! Not about the mailer:) It is strange that question is old but not all answers setup this config and didn't mention simple self assignment

Put such lines into config/application.rb or into specific environment, for example into config/environments/development.rb

After that you can access to routes helpers like this

Rails.application.routes.url_helpers.user_url(25)
# => "https://my.domain:356/users/25"

Upvotes: 0

B Seven
B Seven

Reputation: 45941

Didn't want to change the behavior for other environments, so I used:

development.rb

Rails.application.configure do
...
end

Rails.application.default_url_options = Rails.application.config.action_mailer.default_url_options

Works in Rails 6.

Upvotes: 0

Ahmed J.
Ahmed J.

Reputation: 522

The above answer did not work for me, at least not as I wanted. I realised config.action_mailer.default_url_options = { host: "localhost", port: 3000 } after installing devise. Hope it will help someone with the same problem.

Upvotes: 8

zeeshan
zeeshan

Reputation: 11

I solved the issue by configuring environment.rb as

YourApp::Application.default_url_options = YourApp::Application.config.action_mailer.default_url_options

You need to set default_url_options for action mailer against each environment like development, testing, staging and production etc.

Reference: Missing host to link to! Please provide :host parameter or set default_url_options[:host]

Upvotes: 0

phoet
phoet

Reputation: 18845

just in case someone finds this searching for errors concerning ActiveStorage:

if you have a controller-action where you want to generate upload-urls etc with the local disc-service (most likely in test environment), you need to include ActiveStorage::SetCurrent in the controller in order to allow blob.service_url_for_direct_upload to work correctly.

Upvotes: 5

milad rahmani
milad rahmani

Reputation: 101

go to config/environments/test.rb

Rails.application.routes.default_url_options[:host] = 'localhost:3000'

Upvotes: 6

Derek Fan
Derek Fan

Reputation: 857

Rails.application.routes.default_url_options[:host]= 'localhost:3000'

In the developemnt.rb / test.rb, can be more concise as following:

Rails.application.configure do
  # ... other config ...

  routes.default_url_options[:host] = 'localhost:3000'
end

Upvotes: 21

d11wtq
d11wtq

Reputation: 35318

Your::Application.routes.draw do
  default_url_options :host => "example.com"

  # ... snip ...
end

Somewhere in routes.rb :)

Upvotes: 90

nickh
nickh

Reputation: 4841

The host should be specified in each environment's config file. Eg:

config/environments/development.rb

See this question and this question.

Upvotes: 47

Joshua Pinter
Joshua Pinter

Reputation: 47621

Set default_url_options to use your action_mailer.default_url_options.

In each of your environment files (e.g. development.rb, production.rb, etc.) you can specify the default_url_options to use for action_mailer:

config.action_mailer.default_url_options = { host: 'lvh.me', port: '3000' }

However, these are not set for MyApp:Application.default_url_options:

$ MyApp::Application.config.action_mailer.default_url_options
#=> {:host=>"lvh.me", :port=>"3000"}

$ MyApp::Application.default_url_options
#=> {}

That's why you are getting that error in anything outside of ActionMailer.

You can set your Application's default_url_options to use what you defined for action_mailer in the appropriate environment file (development.rb, production.rb, etc.).

To keep things as DRY as possible, do this in your config/environment.rb file so you only have to do this once:

# Initialize the rails application
MyApp::Application.initialize!

# Set the default host and port to be the same as Action Mailer.
MyApp::Application.default_url_options = MyApp::Application.config.action_mailer.default_url_options

Now when you boot up your app, your entire Application's default_url_options will match your action_mailer.default_url_options:

$ MyApp::Application.config.action_mailer.default_url_options
#=> {:host=>"lvh.me", :port=>"3000"}

$ MyApp::Application.default_url_options
#=> {:host=>"lvh.me", :port=>"3000"}

Hat tip to @pduersteler for leading me down this path.

Upvotes: 46

ivanxuu
ivanxuu

Reputation: 852

When you use any listing_url method the full URL will be returned(not a relative one as normal). That's why rails is asking you for the host, to compute the whole URL.

How you can tell rails the host? You can do it in several ways:

1.Adding this option to each environment:

[/config/development.rb]
config.action_mailer.default_url_options = { host: "localhost:3000" }
[/config/test.rb]
config.action_mailer.default_url_options = { host: "localhost:3000" }
[/config/production.rb]
config.action_mailer.default_url_options = { host: "www.example.com" }

NOTE: If you are working inside a rails engine remember to do the same for your dummy app inside the engine tests: path_to_your_engine/test/dummy/config/environments/* because when you test the engine it's what rails is testing against.

2.Add the host option to the foo_url method like this:

listing_url(listing, host: request.host) # => 'http://localhost:3000/listings/1'

3.Not output the host with the option :only_path to true.

listing_url(listing, only_path: true ) # => '/listings/1'   

IMHO I don't see the point on this one because in this case I would use the listing_path method

Upvotes: 25

Carlos Castillo
Carlos Castillo

Reputation: 3298

You need to add the following line at every environment:

config.action_mailer.default_url_options = { :host => "yourhost" }

That way, it can work in all environments and could be different from environment to environment. For example:

development.rb

config.action_mailer.default_url_options = { :host => "dev.yourhost.com" }

test.rb

config.action_mailer.default_url_options = { :host => "test.yourhost.com" }

production.rb

config.action_mailer.default_url_options = { :host => "www.yourhost.com" }

Upvotes: 309

Okomikeruko
Okomikeruko

Reputation: 1183

I had this same error. I had everything written in correctly, including the Listing 10.13 from the tutorial.

Rails.application.configure do
.
.
.
config.action_mailer.raise_delivery_errors = true
config.action_mailer.delevery_method :test
host = 'example.com'
config.action_mailer.default_url_options = { host: host }
.
.
.
end

obviously with "example.com" replaced with my server url.

What I had glossed over in the tutorial was this line:

After restarting the development server to activate the configuration...

So the answer for me was to turn the server off and back on again.

Upvotes: 2

I am PK
I am PK

Reputation: 6774

Adding the default_url in routes not the right solution although, it works for some cases.

You've to set the default_url in each environment(development, test, production).

You need make these changes.

    config/environments/development.rb
     config.action_mailer.default_url_options = 
      { :host => 'your-host-name' }  #if it is local then 'localhost:3000'

 config/environments/test.rb
      config.action_mailer.default_url_options = 
      { :host => 'your-host-name' }  #if it is local then 'localhost:3000'

  config/environments/development.rb
     config.action_mailer.default_url_options = 
      { :host => 'your-host-name' }  #if it is local then 'localhost:3000'

Upvotes: 0

Undistraction
Undistraction

Reputation: 43401

You can always pass host as a parameter to the URL helper:

listing_url(listing, host: request.host)

Upvotes: 8

pdu
pdu

Reputation: 10423

Funny thing, that setting config.action_mailer.default_url_options does not help for me. Also, messing around with environment-independent settings in places I felt like it does not belong was not satisfying for me. Additionally, I wanted a solution that worked when generating urls in sidekiq/resque workers.

My approach so far, which goes into config/environments/{development, production}.rb:

MyApp::Application.configure do
    # Stuff omitted...

    config.action_mailer.default_url_options = {
      # Set things here as usual
    }
end

MyApp::Application.default_url_options = MyApp::Application.config.action_mailer.default_url_options

This works for me in rails >= 3.2.x.

Upvotes: 16

RicRoberts
RicRoberts

Reputation: 39

You can set default url options in the Application Controller:

class ApplicationController < ActionController::Base
  def default_url_options
    {:locale => I18n.locale}
  end
end

http://guides.rubyonrails.org/action_controller_overview.html#default_url_options

Upvotes: 3

Related Questions