Rails 5 default_url_options oddities - ruby-on-rails

I have a pretty simple rails app that I'm working on upgrading from Rails 4 to Rails 5, but I'm noticing some weirdness with default_url_options
In config/environments/test.rb I have:
Rails.application.routes.default_url_options[:host]= ENV["HTTP_HOST"] || "localhost"
Rails.application.routes.default_url_options[:port]= ENV["PORT"] || 3000
My application has a namespace called api. In my request specs, I'm seeing this:
[1] pry> api_v3_sample_url
=> "http://www.example.com:3000/api/v3/sample"
[2] pry> Rails.application.routes.url_helpers.api_v3_sample_url
=> "http://localhost:3000/api/v3/sample"
What am I missing that is causing those URLs to be different?
EDIT
Per this thread I set
config.action_controller.default_url_options = {
host: ENV['HTTP_HOST'] || 'localhost'
}
in config/environments/test.rb but now I get this:
> Rails.application.routes.url_helpers.api_v3_sample_url
ArgumentError: Missing host to link to! Please provide the :host parameter, set default_url_options[:host], or set :only_path to true
> api_v3_sample_url
=> "http://www.example.com/api/v3/sample"
EDIT 2
Probably worth noting that these are request specs and not feature specs (not using capybara).

This should fix the issue in controller/request specs:
config.action_controller.default_url_options = {
host: ENV['HTTP_HOST'] || 'localhost'
}
As for why this is occurring, there's some more information available in this ongoing thread on Github.

Related

rake task and action_mailer.default_url_options

When I try to use ActionMailer from rake task I'm getting this error:
ActionView::Template::Error: Missing host to link to! Please provide the :host parameter, set default_url_options[:host], or set :only_path to true
In my development.rb I have the following line:
config.action_mailer.default_url_options = { :host => 'localhost:3000' }
Moreover, if I put in development.rb this:
config.action_mailer.default_url_options[:host] = 'localhost:3000'
rake task works fine, but server crashes with this:
config/environments/development.rb:20:in block in ': undefined method []=' for nil:NilClass (NoMethodError)
If I do this:
config.action_mailer.default_url_options = {}
config.action_mailer.default_url_options[:host] = 'localhost:3000
rake task doesn't work again.
I'm confused, any suggestions?
UPD
i don't think that code will help, but here it is, it's that simple:
rake task:
task :send_newsletter => :environment do
Receiver.all.each { |receiver|
NewsletterMailer.newsletter(receiver).deliver
}
end
mailer:
def newsletter(receiver)
#receiver = receiver
mail(to: receiver.email, subject: "newsletter") do |format|
format.html
end
end
and the view with some link_to xxx_url lines, apparently which causing the error
ruby version 2.4.1
rails 5.1.3
rake 12.0.0 (but also tried 12.3.0 with no difference)
Try the following, that should work
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
Update
I don't know what is the ideal solution for this? but I have tested and it working for me
Rails.application.routes.default_url_options = config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
This also work
Rails.application.routes.default_url_options = Rails.application.config.action_mailer.default_url_options
This solution based on this link
And another one is
Rails.application.routes.default_url_options[:host] = '???'
This goes in each environment file - development.rb, test.rb and production.rb (and more if you have them) with the corresponding hostname in each one
Based Link
Hope it will help
solved with this line added to rake task. based on fool-dev's answer
Rails.application.routes.default_url_options = Rails.application.config.action_mailer.default_url_options

Missing host to link to! Please provide the :host parameter, for Rails 4

Missing host to link to! Please provide the :host parameter, set
default_url_options[:host], or set :only_path to true
I randomly get this error at time, generally restarting the server fixes the issue for a while, and then it shows up again.
I have added
config.action_mailer.default_url_options = "localhost:3000", in the development and test.rb files.
Also, I have used include Rails.application.routes.url_helpers
in one module to get access to the routes, I read this could be the reason I get these errors but removing it will leave me with no access to the routes.
The module is for the datatables gem.
For Rails 5, use:
Rails.application.routes.default_url_options[:host] = "XXX"
You can put this in a config/environments/ file (or any other initializer), or e.g. at the beginning of config/routes.rb.
You should write in the following way
For Development(development.rb)
config.action_mailer.default_url_options = { :host => "localhost:3000" }
In production (production.rb)
config.action_mailer.default_url_options = { :host => "myproductionsite.com" }
I had a similar error. The problem is in your configuration.
Try rewriting your configuration for your development.rb and test.rb like this:
config.action_mailer.default_url_options = { host: "localhost", port: 3000 }
Also check that your configuration in production.rb is written correctly like this:
config.action_mailer.default_url_options = { host: 'myherokuapp.herokuapp.com' }
You have updated the default url options for action mailer.
URL helpers will take the option from action_controller settings.
config.action_controller.default_url_options = .....
BR

Devise confirmation link is missing domain

Devise confirmation_url is producing just a relative url with no domain such as:
http://users/confirmation?confirmation_token=...
I tried changing
confirmation_url(#resources, :confirmation_token => #resource.confirmation_token)
to
confirmation_url(:confirmation_token => #resource.confirmation_token)
but it produces the same url. I upgraded to devise 2.2.3 but same outcome. Rails 3.1.4
Update:
I have set in my production.rb:
config.action_mailer.default_url_options = { :host => 'mysubdomain.mysite.com' }
and I tried setting
before_filter set_actionmailer_host
def set_actionmailer_host
ActionMailer::Base.default_url_options[:host] = request.host_with_port
end
to no avail in application controller (https://github.com/plataformatec/devise/issues/1567)
Update:
This occurs in both development and production.
Update
I can't understand why Devise isn't using the template in app/views/devise/mailer/confirmation_instructions.html.haml If I could edit that I could append the host manually: 'http://mysite.com/' + confirmation_url(...
I tried setting the scoped views setting but it didn't have any effect
This is a disaster, users can't confirm their registration :(
You might have missed to add the default url hosts to your environment config-files. When you run the rails g devise:install command you usually receive those instructions.
# config/environments/development.rb
# Default actiomailer url host (required by devise)
config.action_mailer.default_url_options = { host: 'myapp.dev' }
You need this setting for all your environments.
# config/environments/production.rb
# Default actiomailer url host (required by devise)
config.action_mailer.default_url_options = { host: 'myproductionapp.com' }

rspec route testing and hosts

I see I can test routes with rspec like this:
get("/").should route_to("welcome#index")
but I have constraints based on the hostname or parts of hostnames and redirects between several ones. How do I specify a hostname when testing?
How do I run the tests with proper configuration? I tried printing root_url and I got:
Missing host to link to! Please provide the :host parameter, set
default_url_options[:host], or set :only_path to true
The same error happens on mine whenever I run rspec spec/
The entire error is actually:
Failure/Error: #user = Factory(:user)
ActionView::Template::Error:
Missing host to link to! Please provide the :host parameter, set default_url_options[:host], or set :only_path to true
# ./app/views/devise/mailer/confirmation_instructions.html.erb:5:in `_app_views_devise_mailer_confirmation_instructions_html_erb__980323237__638702928'
# ./spec/models/campaign_spec.rb:21
The following line:
# ./app/views/devise/mailer/confirmation_instructions.html.erb:5:in `_app_views_devise_mailer_confirmation_instructions_html_erb__980323237__638702928'
actually gave me the hint that devise is the one throwing out the error.
Turns out I haven't set
config.action_mailer.default_url_options = { :host => 'localhost:3000' }
in config/environments/test.rb (only in development.rb)
Adding the config option cleared out the errors on mine.
I'm suspecting you're using other gems that requires the same option set.
None of the above worked for me. Adding the following to my spec_helper.rb (in my case spec/support/mailer.rb which is included in spec_helper.rb) fixed the error:
Rails.application.routes.default_url_options[:host] = 'test.host'
In my case I had to add
config.action_mailer.default_url_options = { :host => 'localhost:5000' }
to following to
config/environments/test.rb
because I was using FactoryGirl to generate a user without skipping the email_confirmation from user.

How do I set default host for url helpers in rails?

I would like to do something like this
config.default_host = 'www.subdomain.example.com'
in some of my configuration files, so that object_url helpers (ActionView::Helpers::UrlHelper) produce links beginning with http://www.subdomain.example.com
I have tried to search the docs but I did not find anything except ActionMailer docs and http://api.rubyonrails.org/classes/Rails/Configuration.html which is not useful for me, because I do not know in which pat to look. Is there a place which describes the whole structure of Rails::Initializer.config?
asset_host doesn't work for urls
You need to override default_url_options in your ApplicationController (at least in Rails 3)
http://edgeguides.rubyonrails.org/action_controller_overview.html#default-url-options
class ApplicationController < ActionController::Base
def default_url_options
if Rails.env.production?
{:host => "myproduction.com"}
else
{}
end
end
end
Define the default host in your environment config:
# config/environments/staging.rb
MyApp::Application.configure do
# ...
Rails.application.routes.default_url_options[:host] = 'preview.mydomain.com'
# ...
end
Then you can create a URL anywhere in your app:
Rails.application.routes.url_helpers.widgets_url()
Or include the URL helpers in your class:
class MyLib
include Rails.application.routes.url_helpers
def make_a_url
widgets_url
end
end
If you don't define the default host, you will need to pass it as an option:
widgets_url host: (Rails.env.staging? ? 'preview.mydomain.com' : 'www.mydomain.com')
It's also useful to specify things like the protocol:
widgets_url protocol: 'https'
Another way is to set it like this
# config/production.rb
config.action_controller.default_url_options = { host: 'myproduction.com' }
You can easily set :host or/and :only_path parameter for every url_helper.
yours_url(params, :host => "http://example.com", :only_path => Rails.env.test?)
This way you are not setting global default_url_options in your environments, unless you want that.
In Rails 6.1 (at least), application-wide default_url_options can be set as follows:
# config/environments/development.rb
Rails.application.default_url_options = { host: 'localhost', port: 3000 }
Rails.application.configure do
# ...
end
See: https://github.com/rails/rails/issues/29992#issuecomment-761892658
As far as I know, the *_url helpers use the server's configured host name. So for example if my Apache installation is accepting requests for this Rails app at http://www.myapp.com/ then Rails will use that address. That's why the *_url methods in a development environment point to http://localhost:3000 by default.
The asset host suggested in the previous answer will only affect the image_tag, stylesheet_link_tag and javascript_link_tag helpers.
NSD's solution is how I do it, but I had to add a block to make it work with https:
config.action_controller.asset_host = Proc.new { |source, request|
(request ? request.protocol : 'http://') + "www.subdomain.example.com"
}
There's this, but I'm not terribly sure if they're the helpers you're referring to:
ActionController::Base.asset_host = "assets.example.com"
http://api.rubyonrails.org/classes/ActionView/Helpers/AssetTagHelper.html

Resources