28

I'm writing a small Ruby program that will pull records from a database and send an HTML email daily. I'm attempting to use ActionMailer 3.0.3 for this, but I'm running in to issues. All the searching I've done so far on using ActionMailer outside of Rails applies to versions prior to version 3. Could someone point me in the right direction of where to find resources on how to do this? Here's where I am so far on my mailer file:

# lib/bug_mailer.rb
require 'action_mailer'

ActionMailer::Base.delivery_method = :file

class BugMailer < ActionMailer::Base
  def daily_email
    mail(
            :to      => "example@mail.com",
            :from    => "example@mail.com",
            :subject => "testing mail"
    )
  end
end

BugMailer.daily_email.deliver

I'm definitely stuck on where to put my views. Every attempt I've made to tell ActionMailer where my templates are has failed.

I guess I should also ask if there's a different way to go about accomplishing this program. Basically, I'm doing everything from scratch at this point. Obviously what makes Rails awesome is it's convention, so is trying to use parts of Rails on their own a waste of time? Is there a way to get the Rails-like environment without creating a full-blown Rails app?

Spencer R
  • 1,118
  • 2
  • 14
  • 34

2 Answers2

49

After some serious debugging, I found how to configure it.

file mailer.rb

require 'action_mailer'

ActionMailer::Base.raise_delivery_errors = true
ActionMailer::Base.delivery_method = :smtp
ActionMailer::Base.smtp_settings = {
   :address   => "smtp.gmail.com",
   :port      => 587,
   :domain    => "domain.com.ar",
   :authentication => :plain,
   :user_name      => "test@domain.com.ar",
   :password       => "passw0rd",
   :enable_starttls_auto => true
  }
ActionMailer::Base.view_paths= File.dirname(__FILE__)

class Mailer < ActionMailer::Base

  def daily_email
    @var = "var"

    mail(   :to      => "myemail@gmail.com",
            :from    => "test@domain.com.ar",
            :subject => "testing mail") do |format|
                format.text
                format.html
    end
  end
end

email = Mailer.daily_email
puts email
email.deliver

file mailer/daily_email.html.erb

<p>this is an html email</p>
<p> and this is a variable <%= @var %> </p>

file mailer/daily_email.text.erb

this is a text email

and this is a variable <%= @var %>

Nice question! It helped me to understand a bit more how Rails 3 works :)

Augusto
  • 28,839
  • 5
  • 58
  • 88
  • Thanks...that helped. So, where I'm stuck next is where to put my views. I know that, if I were creating a Rails app, they would live in `app/views`, but I have no idea where I should put my views. For now my view is as follows: `lib/bug_mailer/daily_email.html.erb`. Any ideas? – Spencer R Feb 11 '11 at 21:59
  • Ha, stackoverflow has all the answers :) http://stackoverflow.com/questions/741989/actionmailer-and-ramaze – Augusto Feb 11 '11 at 22:25
  • That was actually the very first post I looked at in researching ActionMailer outside of Rails. I followed the method mentioned there, but no go. Here's how I've got everything set up currently. The mailer is here: `bugs_email/lib/bug_mailer.rb`. The view is here: `bugs_email/lib/bug_mailer/daily_email.html.erb`. So unless I'm missing something (which is possible!) I'm set up like that example. – Spencer R Feb 11 '11 at 23:03
  • I'm not sure if this is really "proper" or not, but I came up with a solution by doing some digging through the mail gem files. I added this line to the `mail()` method call inside my `daily_email` method `:body => File.read(File.dirname(__FILE__) + "/../views/bug_mailer/daily_email.html.erb")`. So, for now, I'm cookin' with gas! – Spencer R Feb 11 '11 at 23:41
  • 3
    yipee! I found the solution!!! :D... I'm quite new to ruby & rails, so this was a really good challenge :) – Augusto Feb 12 '11 at 12:06
  • Thanks, again. And thanks for the code. That'll save me some steps on Monday :) I should also mention something that was tripping me up along the way (incase someone else comes across this question and is having the same problem) I had completely forgotten that my network at work blocks outgoing SMTP connections. So, at times when I was on the right track, I didn't realize it because I wasn't able to connect to gmail. – Spencer R Feb 13 '11 at 00:04
  • Thanks for this! The only problem I had was that the mailer couldn't find the templates. It turned out to be the filenames. When I renamed myfile.html.erb to myfile.erb it worked fine. – Julian Mann Apr 15 '11 at 15:17
  • https://github.com/shadowbq/actionmailer_standalone_example - Thought this might help. – shadowbq Mar 23 '15 at 16:43
2

It took me a while to get this to work in (non-)Rails 4. I suspect it's just because I have ':require => false' all over my Gemfile, but I needed to add the following to make it work:

require 'action_view/record_identifier'
require 'action_view/helpers'
require 'action_mailer'

Without the above code, I kept getting a NoMethodError with undefined method 'assign_controller'.

After that, I configured ActionMailer as follows:

ActionMailer::Base.smtp_settings = {
  address: 'localhost', port: '25', authentication: :plain
}
ActionMailer::Base.default from: 'noreply@example.com'
ActionMailer::Base.raise_delivery_errors = true
ActionMailer::Base.logger = Logger.new(STDOUT)
ActionMailer::Base.logger.level = Logger::DEBUG
ActionMailer::Base.view_paths = [
  File.join(File.expand_path("../../", __FILE__), 'views', 'mailers')
  # Note that this is an Array
]

The templates go in lib/<GEM_NAME>/views/mailers/<MAILER_CLASS_NAME>/<MAILER_ACTION_NAME>.erb (MAILER_ACTION_NAME is the public instance method of your mailer class that you call to send the email).

Lastly, don't forget to put this in your spec_helper:

ActionMailer::Base.delivery_method = :test
Isaac Betesh
  • 2,935
  • 28
  • 37