I have a need to send out a bunch of individual emails from the same email address. I thought it would be good practice for me to see if I could do this as part of a rails app. The interesting thing is that I don’t want to save anything to a model. I just want to be able to upload a csv file, get all the names and email addresses out and send the same email with attachment to all of them. Here’s how I did it.

Here’s my standalone model

class Message
  include ActiveModel::Validations
  include ActiveModel::Conversion
  extend ActiveModel::Naming

  attr_accessor :name, :email, :doc
  validates_presence_of :name, :email
  
  def initialize(attributes = {})
    attributes.each do |name, value|
      send("#{name}=", value)
    end
  end

  def persisted?
    false
  end

  def send_announcement
    pid = fork do
      GeneralMailer.send_announcement(self).deliver
    end
    Process.detach(pid)
  end
end
class MessagesController < ApplicationController
  filter_access_to :all, :attribute_check => false

  def index
  end

  def new
    @message = Message.new
  end

  def create
    @file = IO.readlines(params[:message][:doc].tempfile)
    @file.each do |line|
      @a = line.chomp.split(',')
      @message = Message.new(name: @a[1], email: @a[0])
      if @message.valid?
        @message.send_announcement
      end
    end
    redirect_to new_message_path
  end

end
<%= form_for(@message) do |f| %>
  

Text file of email addresses: <%= f.file_field :doc %>

<%= f.submit %>

<% end %>
class GeneralMailer < ActionMailer::Base
  default from: "sending_email_address"

  def send_announcement(message)
    @message = message
    attachments['color_test.pdf'] = File.read('/Users/me/Desktop/color-test.pdf')
    mail(to: "#{@message.name}<#{@message.email}>", subject: "2014 Conference")
  end
end

I don’t really need the index method, but my form complained when it wasn’t there. I haven’t had a chance to look into why that is. I also tried using a form_tag form, but that didn’t upload the document. So I’m sure there’s a better way of doing this, but this actually does do what I want.