RobL Vs

Background

ActionMailer with ActiveRecord validation

I wanted to be able to send out a mail from a controller but also validate the incoming args in a clean way. Like so…

 1class MessagesController < ActionController::Base
 2
 3def deliver
 4  @message = Message.build(params[:message])
 5  if @message.deliver
 6    redirect_to home_path
 7  else
 8    render :action
 9  end
10end

ActionMailer::Base hides the initialize methods in method_missing and most of the time you are calling ActionMailer::Base.deliver_mymail(args). This allows you to specify all of the standard actionmailer settings in Message.build and return a Message object.

 1class Message < ActionMailer::Base
 2
 3  include Validatable
 4  validates_presence_of :from, :body
 5
 6  def self.build(args = {})
 7    new('default', args)
 8  end
 9
10  def self.action_mailer_methods
11    return [
12      :bcc,
13      :body,
14      :cc,
15      :charset,
16      :content_type,
17      :from,
18      :reply_to,
19      :headers,
20      :implicit_parts_order,
21      :mime_version,
22      :recipients,
23      :sent_on,
24      :subject,
25      :template
26    ]
27  end
28
29  def default(args)
30    new_args = args.clone
31    new_args.each do |k,v|
32      if self.class.action_mailer_methods.include?(k)
33        send(k, new_args.delete(k))
34      end
35    end
36
37    if body.kind_of?(Hash)
38      @body.merge!(new_args)
39    end
40
41  end
42
43  def deliver
44    if self.valid?
45      return deliver!
46    else
47      return false
48    end
49  end
50
51end