如何在每个环境中设置config.action_controller.default_url_options = {:host = '#''}

72

目前我正在使用这个方法,它适用于开发主机,但当我切换到生产环境时,我必须手动更改{:host => ""}代码。

post.rb

def share_all
  url =  Rails.application.routes.url_helpers.post_url(self, :host => 'localhost:3000')
  if user.authentications.where(:provider => 'twitter').any?
    user.twitter_share(url)  
  end
end

我想使用这个功能,并根据环境定义 default_url_options:

post.rb

def share_all
  url =  Rails.application.routes.url_helpers.post_url(self)
  if user.authentications.where(:provider => 'twitter').any?
    user.twitter_share(url)  
  end
end

我尝试将以下内容添加到我的config/environments/development.rb文件中,但仍然出现“缺少链接的主机!请提供:host参数或设置default_url_options [:host]”错误。

development.rb

config.action_controller.default_url_options = {:host => "localhost:3000"}

我甚至尝试过这种方式:

development.rb

config.action_controller.default_url_options = {:host => "localhost", :port => "3000"}

编辑:

我现在也按照此操作,但仍然遇到相同的错误,请参考http://edgeguides.rubyonrails.org/action_controller_overview.html#default_url_options

应用程序控制器

class ApplicationController < ActionController::Base
  protect_from_forgery
  include ApplicationHelper
  def default_url_options
    if Rails.env.production?
      { :host => "example.com"}
    else
      {:host => "example1.com"}
    end
  end
end

这让我疯狂,我错过了什么???

9个回答

130

好的,我想出了正确的写法。

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

:)


6
如果您使用动态主机,则不是线程安全的。我只发现一种方法,就是通过before_filter在ApplicationController中设置Thread.current,并在Model中使用此主机。 - Dmitry Polushkin
5
能否从config.routes或类似的地方进行设置? - sites
1
@juanpastas:我刚刚将它添加到了routes.rb的顶部:Example::Application.routes.default_url_options[:host] = 'example.com' - lime
1
就我个人而言,我认为最好使用_path助手而不是url助手来解决这个问题...即相对路径与绝对URL。 :) 这通常是rspec的一个问题。 - engineerDave
仅切换到_path助手只能有所帮助。例如,如果您使用redirect_to,则在幕后调用url_for,因此每次调用它时都需要传递:only_path => true。 - jxpx777
显示剩余4条评论

12

ActionMailer继承您的应用程序的default_url_options

尽可能地保持DRY,理想情况下,您不希望在相同环境的多个地方硬编码主机和端口,除非您的ActionMailer确实使用不同的主机和端口,而不是您的整个Application

要为整个Application设置default_url_options,只需将以下行添加到您的config/environment.rb文件中(将MyApp更改为您的应用程序名称):

# 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

这将解决您的问题,并自动将Applicationdefault_url_options设置为与您的config.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"}

1
如果您这样做,您可能希望在您的Action Mailer default_url_options上方添加一条注释,说明应用程序default_url_options会继承它们。不希望有人更改Action Mailer default_url_options而没有意识到它将为整个应用程序更改它们。 - David Gay
@DavidGay 同意。理想情况下,我更愿意明确设置 default_url_options,然后指定 action_mailer.default_url_options 从中继承。但由于某种原因,我在2.5年前没有这样做。 - Joshua Pinter

7

在这个文件的更改生效之前,您需要重新启动服务器。


2
我已经重启了我的服务器大约10次来尝试这个,但是没有用。 - trying_hal9000

6

config/environments/development.rb (其他环境同理)

在该文件中添加一行,填写您想要的主机名称。

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

5

配置.action_mailer.default_url_options = { :host => "你的主机" }

例如,你的主机为localhost:3000

你可以将这个配置放在test.rb、development.rb、production.rb文件中,不同的环境下主机可能会有所不同。


2
这是我通常解决这个问题的方式:
首先,正确设置你的config/environments/production.rb文件(以及其他环境),从rails new自动生成的文件开始:
Rails.application.configure do
  # [...]
  config.action_mailer.default_url_options = {
    host: "https://your_app.your_domain.tld"
  } # You may also use an env variable ENV['HOST'] if necessary
end

然后,返回到你的config/application.rb文件,并设置继承此ActionMailer配置:

require_relative "boot"
require "rails/all"
Bundler.require(*Rails.groups)

module YourModule
  class Application < Rails::Application
    # [...]
    config.after_initialize do |app|
      app.routes.default_url_options = app.config.action_mailer.default_url_options
    end
  end
end

最佳答案 :D 上述解决方案对我无效,default_url_options 一直是 nil。在 after_initialize 中使其工作。Rails 7.1 - undefined

2
我知道这是一个旧的线程,但我在 Ruby 2.6.3 和 Rails 5.2.3 中遇到了这个问题。 我看到的行为基本上是,我添加的每个路径都会失败,并显示“Error during failsafe response: undefined method 'empty?' for nil:NilClass”。在生产环境中它工作正常,但在我的开发环境中,我会得到上面提到的错误。
对我来说解决方法是将以下内容添加到 controllers/application_controller.rb:
def default_url_options
  if Rails.env.production?
    Rails.application.routes.default_url_options = { host: "www.production-domain.com", protocol: 'https' }
  elsif Rails.env.development?
    Rails.application.routes.default_url_options = { host: 'localhost:3000', protocol: 'http' }
  end
end

我随后能够在本地运行我的开发环境。


1
我是一名有用的助手,可以为您翻译文本。

我自己遇到了这个问题,试图在一个Rake任务中生成URL。这绝对不是显而易见的,许多解决方案都可以起作用。我的解决方案是基于@joshua-pinter的方法,在环境文件中完成。例如,我的development.rb看起来像:

Rails.application.configure do
  …
  config.action_mailer.default_url_options = self.default_url_options = { host: 'localhost', port: 3000 }
  …
end

production.rb进行适当更改。


0

对我来说有效的是

ActionMailer::Base.default_url_options = { host: "yourhosthere"} # e.g. yourhosthere=localhost:3000 or yourhosthere=example.com

因为如果您已经在配置文件中设置了端口,那么仅更改[:host]将导致错误。

TypeError (no implicit conversion of Symbol into Integer):

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接