2

I am working on an application that has set its default host to localhost:

config.action_controller.default_url_options = { host: "localhost" }
config.action_mailer.default_url_options = { host: "localhost" }

This works fine if you're serving your app on a specific port (like http://localhost:3000). I am using Pow so that I can access the app from a URL like http://myapp.dev.

How can I change this setting so that it will work with my domain as well as the other developers using localhost? I need to generate full URLs since they will be used in emails. Is it possible to pass some sort of config value to Pow?

Andrew
  • 227,796
  • 193
  • 515
  • 708
  • I think this question may have the answers you need: http://stackoverflow.com/questions/3432712/action-mailer-default-url-options-and-request-host – odigity Jan 21 '15 at 22:20

6 Answers6

2

This is the best way I found:

1- Create a config/smtp_settings.example.yml file:

development:
  :method: :letter_opener
  :url_options:
    :host: localhost
    :port: 3000

production: &production
  :method: :smtp
  :url_options:
    :host: www.the_site.com
  :smtp_settings:
    address: smtp.gateway.com
    port: 465
    user_name: someone@somewhere.com
    # etc ...

staging:
  <<: *production

test:
  :method: :test
  :url_options:
    :host: test.host

Notes:

  • This uses letter_opener as development mailer, change to your own method
  • There is a staging environment defined as an exact copy of the production environment, remove if you don't use staging

2- Remove config.action_mailer.delivery_method and config.action_mailer.default_url_options and config.action_mailer.smtp_settings from all files under config/environments/ folder

3- Add in the file config/application.rb the following:

config.action_mailer.delivery_method = config_for(:smtp_settings)[:method]
config.action_mailer.default_url_options = config_for(:smtp_settings)[:url_options]
config.action_mailer.smtp_settings = config_for(:smtp_settings)[:smtp_settings] if config_for(:smtp_settings)[:method] == :smtp

Notes: config_for has been introduced in the latest version of Rails (4.2.0 as per writing). If you use an older version of rails you must manually load the yml files


And the trick on top of all of that to answer your question:

Push to your repository the file config/smtp_settings.example.yml and ignore the file config/smtp_settings.yml.

Each developper of your team would have to create their own config/smtp_settings.yml by copying the file smtp_settings.example.yml and changing the host to match their machine's IP address, so the mail send by each developer leads to their own machine.

You off course requires you to start the local development server binded to 0.0.0.0 so it's accessible from other hosts (considering your security environment off course)

Benjamin Bouchet
  • 12,971
  • 2
  • 41
  • 73
1

In development, I like to use dotenv gem(https://github.com/bkeepers/dotenv).

I put in .env :

DOMAIN=myapp.dev

And I put inside config/route.rb: MyApplication::Application.routes.draw do default_url_options host: ENV['DOMAIN']

In production I define on heroku my domain with this command :

h config:set DOMAIN=myapp.herokuapp.com

or with a custom domain :

h config:set DOMAIN=superdomain.com

Luc Boissaye
  • 935
  • 8
  • 14
1

This will check if Application root directory is symlinked in .pow of current user and set the host accordingly.

if File.exists?(Dir.home+"/.pow/#{Rails.root.basename}")
  config.action_mailer.default_url_options = { host: "#{Rails.root.basename}.dev" }
else
  config.action_mailer.default_url_options = { host: "localhost" }
end
  • Ooh, that's an interesting idea! – Andrew Jan 23 '15 at 17:35
  • Hmm...this doesn't work for me because the `Rails.root.basename` is not the same as the name of the symlink. Also, it is not flexible because it would not allow other developers to name their symlinks something else. – Andrew Jan 23 '15 at 23:40
1

You could use an environment variable to configure a default host. See Luc Boissaye's answer on how to set this up with dotenv. If you don't add the .env to your repo, each developer can create his own .env and configure his (or her) own preferences.

But you can also use existing environment variables to configure the default_url_options. For example Pow.cx sets the POW_DOMAINS variable:

config.action_mailer.default_url_options = {
  ENV['POW_DOMAINS'].present? ? 'my-app.dev' : 'localhost' 
}

As far as I know you only need to set the config.action_controller.default_url_options if you want to force it to some default. When you use the rails _path helpers in your views, this will generate a relative URL (/path). If you use the _url helpers, this will generate an absolute URL (http://your.host/path), but both the protocol (http) and host (your.host) are request based.

Community
  • 1
  • 1
hjblok
  • 2,936
  • 22
  • 20
  • Hmm...I liked this solution, but it didn't work for me. `ENV['POW_DOMAINS']` was nil – Andrew Jan 23 '15 at 23:33
  • You can add an `logger.info ENV.inspect` somewhere in your Rails code to see which environment variables are defined. You could also add your custom environment variable to `~/.powconfig` (see the [Pow user manual](http://pow.cx/manual.html#section_3)) – hjblok Jan 24 '15 at 12:47
  • The closest thing I could find was: `ENV["XPC_SERVICE_NAME"] == "cx.pow.powd"` – Andrew Jan 27 '15 at 20:06
  • Does not make sense to accept an answer with an obsolete technique. Rails 4.2 introduced `config_for`, and the answer bellow is talking about it. You guys should read the rails' change logs and keep yourself informed – Benjamin Bouchet Jan 28 '15 at 20:55
0

Described on Action Mailer Basics:

Unlike controllers, the mailer instance doesn't have any context about the incoming request so you'll need to provide the :host parameter yourself.

As the :host usually is consistent across the application you can configure it globally in config/application.rb:

config.action_mailer.default_url_options = { host: 'example.com' }

Because of this behavior you cannot use any of the *_path helpers inside of an email. Instead you will need to use the associated *_url helper. For example instead of using

<%= link_to 'welcome', welcome_path %>

You will need to use

<%= link_to 'welcome', welcome_url %>

The use of Pow makes things a little trickier but thankfully it integrates with XIP.io so you can access myapp.dev from machines on the local network. Just follow the instructions here: Accessing Virtual Hosts from Other Computers.

The question doesn't mention this, but it might be useful information - If you'd like to actually send mail in your dev (or perhaps test/staging) environment, Instead of seeing mail just in the rails console (with something like powder applog), I'd recommend just hooking it up to a gmail.

Archonic
  • 5,207
  • 5
  • 39
  • 55
0

You need to override default_url_options in your application controller (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

djadam
  • 649
  • 1
  • 4
  • 20