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
Related
In a controller I call a service like:
MyService.call
In the MyService.call method I want to use a url helper:
Rails.application.routes.url_helpers.something_url
However, I get the error:
Missing host to link to! Please provide the :host parameter, set default_url_options[:host], or set :only_path to true
in config/environments/development.rb I have:
config.action_mailer.default_url_options = { host: 'localhost:3000' }
config.action_controller.default_url_options = { host: 'localhost:3000' }
What should I set not to get the error?
You could set the host in the config files as:
Rails.application.routes.default_url_options[:host] = 'your_host'
This will set the default host not just for action_mailer and action_controller, but for anything using the url_helpers.
According to this thread, whenever using route helpers, they don't defer default_url_options to ActionMailer or ActionController config and it is expected that there will be a default_url_options method in the class. This worked for me:
class MyService
include Rails.application.routes.url_helpers
def call
something_url
end
class << self
def default_url_options
Rails.application.config.action_mailer.default_url_options
end
end
end
Note that you can use action_mailer or action_controller config depending which you've configured.
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
In my production.rb I set my asset_host to CloudFront like so:
config.action_controller.asset_host = 'http://xxxxxxxx.cloudfront.net'
Now I'm finding that in some circumstances (specifically, outputting JavaScript to be embedded into another site) I need to set the asset_host in the development environment too, the default null won't cut it. Ideally I want to set:
config.action_controller.asset_host = 'http://localhost:3000'
but this port can't be guaranteed, and I'm reluctant to hard-code it. Is there a way to set asset_host to the current domain and port?
Thanks!
You can make use of environment variables or Rails initializer parameters
config.action_controller.asset_host = ENV[ASSET_HOST].empty? ? 'http://' + Rails::Server.new.options[:Host] + ':' + Rails::Server.new.options[:Port] : ENV[ASSET_HOST]
This way if you set the environment variable you use that address otherwise it will use the default.
In Rails 4 we use a dynamic asset_host setting with a proc:
# in /config/environments/development.rb
Rails.application.configure do
config.action_controller.asset_host = Proc.new { |source, request|
# source = "/assets/brands/stockholm_logo_horizontal.png"
# request = A full-fledged ActionDispatch::Request instance
# sometimes request is nil and everything breaks
scheme = request.try(:scheme).presence || "http"
host = request.try(:host).presence || "localhost:3000"
port = request.try(:port).presence || nil
["#{scheme}://#{host}", port].reject(&:blank?).join(":")
}
# more config
end
This code ensures that requests from localhost:3000, localhost:8080, 127.0.0.1:3000, local.dev and any other setup just work.
This value is available during startup and might help:
Rails::Server.new.options[:Port]
Try adding it to the asset_host variable of your development.rb file.
Based on this answer: https://stackoverflow.com/a/13839447/1882605
Try:
class ApplicationController < ActionController::Base
before_filter :find_asset_host
private
def find_asset_host
ActionController::Base.asset_host = Proc.new { |source|
if Rails.env.development?
"http://localhost:3000"
else
{}
end
}
end
I have a Sidekiq worker that is intended to perform social actions (e.g.: like pages on Facebook). Part of this requires knowing the URL for the object being liked.
Fortunately, Rails 3 makes it easy to access app-specific routes by including Rails.application.routes.url_helpers in whatever class or module needs access to the path/url helper method.
The problem I'm running into is that my default url/port are not accessible from within my Sidekiq worker despite various attempts to define them in my development.rb or production.rb.
class Facebook::LikeRecipeWorker
include Sidekiq::Worker
include Rails.application.routes.url_helpers
sidekiq_options queue: :facebook
def perform(recipe_id, user_id)
recipe = Recipe.find(recipe_id)
user = User.find(user_id)
if user.facebook_token
api = Koala::Facebook::API.new(user.facebook_token)
api.put_connections 'me', 'my_namespace:like', object: recipe_url(recipe)
end
end
end
When the recipe_url method is access, an ArgumentError is raised with the message:
ArgumentError: Missing host to link to! Please provide the :host parameter, set default_url_options[:host], or set :only_path to true
I know that I can specify default_url_options for ActionController or ActionMailer in the environment-specific config files, e.g.:
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
config.action_controller.default_url_options = { host: 'localhost', port: 3000 }
However, these (rightfully) appear to have no influence on my Sidekiq worker classes. How should I go about defining default_url_options for these classes?
What we did was this:
In your config file(s) (e.g. config/application.rb, config/production.db, etc.), have a line that sets the default:
routes.default_url_options = { host: 'www.example.org' }
I found a potential solution to this, though it feels like a little bit of a hack. I'm definitely open to better answers.
First, in my environment files (e.g.: config/environments/development.rb), I specify the default_url_options for my controllers:
config.action_controller.default_url_options = { host: 'localhost', port: 3000 }
Then in my worker class, I define a default_url_options instance method there:
class Facebook::LikeRecipeWorker
# ...
private
def default_url_options
ActionController::Base.default_url_options
end
end
I currently have a setup where I force SSL or http where I need it with this before_filter in my application controller:
def force_ssl
if params[:controller] == "sessions"
if !request.ssl? && Rails.env.production?
redirect_to :protocol => 'https://', :status => :moved_permanently
end
else
if request.ssl? && Rails.env.production?
redirect_to :protocol => 'http://', :status => :moved_permanently
end
end
end
What I'd like to do is to use https://secure.example.com when using SSL but keep using http://example.com when not using SSL. Is there a way I can switch between the hostnames depending on whether I'm using SSL?
First I'll show how to force SSL in current and earlier versions of Rails, then at the end I've posted how to use HTTP and HTTPS in Parallel with each other, which is what I think your looking for.
Rails >= 3.1
Simply use config.force_ssl = true in your environment configuration.
# config/application.rb
module MyApp
class Application < Rails::Application
config.force_ssl = true
end
end
You can also selectively enable https depending on the current Rails environment. For example, you might want to keep HTTPS turned off on development, and enable it on staging/production.
# config/application.rb
module MyApp
class Application < Rails::Application
config.force_ssl = false
end
end
# config/environments/production.rb
MyApp::Application.configure do
config.force_ssl = true
end
Rails < 3.1
Just in case you have any projects that are not Rails 3.1 and want the same feature. Enable HTTPS by adding the following line to your environment configuration.
config.middleware.insert_before ActionDispatch::Static, "Rack::SSL"
Note that I’m passing Rack::SSL as string to delegate the loading of the class at the end of the Rails application initialization. Also note the middleware must be inserted in a specific position in the stack, at least before ActionDispatch::Static and ActionDispatch::Cookies.
Don’t forget to define Rack::SSL dependency in your Gemfile.
# Gemfile
gem 'rack-ssl', :require => 'rack/ssl'
Enabling HTTPS and HTTP in parallel
Rack::SSL has a very interesting and undocumented feature. You can pass an :exclude option to determine when to enable/disable the use of HTTPS.
The following code enables Rack::SSL and all its filters only in case the request comes from a HTTPS connection.
config.middleware.insert_before ActionDispatch::Static, Rack::SSL, :exclude => proc { |env| env['HTTPS'] != 'on' }
Both the following URLs will continue to work, but the first one will trigger the Rack::SSL filters.
https://secure.example.com
http://example.com