ActionMailer configuration API

103 views
Skip to first unread message

Amiel Martin

unread,
May 5, 2013, 9:04:27 PM5/5/13
to rubyonra...@googlegroups.com
Hello,

TL;DR: I'd like to move ActionMailer configuration to confg/mail.yml (just like config/database.yml). In order to make that possible (in a sane way), I would like to standardize the way ActiveRecord and ActionMailer are configured.


As I was poking around to see how I would implement configuring ActionMailer with config/mail.yml, I was reminded how different the configuration APIs for ActiveRecord and ActionMailer are.
My plan is to make the ActionMailer configuration api mirror the ActiveRecord configuration api. That is, the following should work:

# current ActiveRecord configuration
ActiveRecord::Base.configurations = {
  development: {
    adapter:    "postgresql",
    host:       "localhost",
    database:   "myapp_development",
    username:   "rails",
    password:   "sekret",
  },
  test: {
    adapter:    "sqlite3",
    database:   "db/test.sqlite3",
    pool:       5,
    timeout:    5000,
  },
  production: { } # ... etc
}

# proposed ActionMailer configuration
ActionMailer::Base.configurations = {
  development: {
    adapter:    "sendmail",                     # renamed from delivery_method to match ActiveRecord
    location:   "/usr/sbin/sendmail",
    arguments:  "-i -t",
  },
  test: { adapter: "test" },                    # this would be the default
  production: {
    adapter:          "smtp",
    host:             "smtp.sendgrid.net",      # renamed from address
    port:             "587",
    authentication:   :plain,
    username:         ENV["SENDGRID_USERNAME"], # renamed from user_name
    password:         ENV["SENDGRID_PASSWORD"],
  },
}


I chose to make ActionMailer like ActiveRecord because I think that more people know ActiveRecord's configuration. However, if there is something about the way ActionMailer is configured that is desired, then ActiveRecord's configuration could also be changed (although it seems like it would be harder to change and deprecate ActiveRecord configuration).

A few thoughts:

* ActionMailer stores configuration for each delivery method (`smtp_settings`, `sendmail_settings`). I'm not sure why this is, but to me it makes more sense to flatten this configuration structure and split it up by environment.
* This would be a major configuration change. If the change is accepted, I would write graceful deprecation and perhaps a migration helper.
* I mentioned this idea to Aaron Patterson at Railsconf. He brought up the idea of having a more generic configuration storage mechanizm. While I'm not specifically working on that, I think this is a step in that direction.

A few questions:

* Any thoughts in general? Is this a good idea? Does anyone have major problems with this?
* Does it make sense to rename configuration options such as renaming `address` to `host` in order to match the ActiveRecord configuration options more closely? Once again, I would make sure to not break existing configurations.
* Is there anything about the current ActionMailer configuration api that is better than ActiveRecord's?

I will start chipping away at this, and probably come back with more questions after a first pass. 
I would apreciate any initial feedback.

Thank you for your time,


-Amiel

Richard Schneeman

unread,
May 6, 2013, 12:17:32 AM5/6/13
to rubyonra...@googlegroups.com
Storing configuration in your git repository is not the greatest thing on earth: http://www.12factor.net/config

At least by pulling it from code it becomes very easy to assign to ENV Variables. 

-- 
Richard Schneeman

Amiel Martin

unread,
May 7, 2013, 12:16:50 PM5/7/13
to rubyonra...@googlegroups.com
Richard,

I agree that storing configuration in git is not ideal.

My hope is that:

1. moving mail configuration to mail.yml will encourage mail configuration to be treated more like database configuration is now (by default, database.yml is not included in git; and a database.yml.example is provided).
2. if the configuration apis are the same, any future efforts that change the way ActiveRecord is configured, will more easily apply to ActionMailer as well.

Thanks for your response,


-Amiel
--
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-co...@googlegroups.com.
To post to this group, send email to rubyonra...@googlegroups.com.
Visit this group at http://groups.google.com/group/rubyonrails-core?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Brian Moseley

unread,
May 7, 2013, 12:50:34 PM5/7/13
to rubyonra...@googlegroups.com
if anything, I'd rather see database.yml go away and have AR configured through the application config api instead. the current state of affairs makes it more difficult to e.g. use an external configuration repository like ZooKeeper. that will continue to be true as long as AR has no documented public configuration api and simply expects the user to provide database.yml (the half-baked DATABASE_URL environment variable support notwithstanding). please don't send AM down the same path and make the situation even worse.

Amiel Martin

unread,
May 20, 2013, 6:46:58 PM5/20/13
to rubyonra...@googlegroups.com
Brian, I see your point.

I actually think that this project will actually benefit you. My goal is to standardize the api in which ActiveRecord and ActionMailer are configured.
I don't think I can decide to make this public, but I think that with the standardization will also come API stability.

Another problem is that database.yml is required, so you can't configure ActiveRecord programmatically.
I don't see database.yml going away, but it would be nice if rails didn't raise an exception on boot when it can't find database.yml.

Another similar approach to what I had before could be this configuration API:

ActiveRecord::Base.configuration = {
  adapter:    "postgresql",
  host:       "localhost",
  database:   "myapp_development",
  username:   "rails",
  password:   "sekret",
}

ActionMailer::Base.configuration = {
  adapter:    "sendmail",
  location:   "/usr/sbin/sendmail",
  arguments:  "-i -t",
}

ActiveRecord::Base would still respond to .configurations, which would just throw away configurations for any environments but the current one.

This would make configuring ActiveRecord and ActionMailer programmatically easier.
What do you think?

Anyone else have opinions on this before I get started?


-Amiel

Brian Moseley

unread,
May 20, 2013, 7:23:54 PM5/20/13
to rubyonra...@googlegroups.com
sounds fine to me.

I have a separate issue with having a static single-environment configuration like this because it's the root cause of some other problems I've had with database configuration, but describing that would just confuse this issue and can wait til another day.

thanks for your response!

Amiel Martin

unread,
May 28, 2013, 9:24:37 PM5/28/13
to rubyonra...@googlegroups.com
Ok,


So far, I've just got the ActionMailer::Base.configuration api as well as deprecated support for the previous ActionMailer::Base.xxx_settings api.

Adding mail.yml at this point is trivial. Any thoughts on this before I send in a pull-request?

Thanks,

-Amiel
Reply all
Reply to author
Forward
0 new messages