Search code examples
ruby-on-railsemailmailer

Sending a confirmation email without creating a model/controller and use of a db?


I've created a single page landing site which contains a simple waitlist form that dumps the info into a google doc (trying to keep it low tech for now, since an app will be built on top of this as well).

I'm trying to send the people who submit their email address for the waiting list a confirmation email. Can I pass the email address to a mailer without creating a model/controller and use of a db?

I've done this before by creating a model/controller (see below code) and use of a db (postgreSQL / Heroku), but it seems messy for such a simple task.

Here's my setup in the past, looking to get rid of the model/controller and pass the email address (w/ .downcase transformation) to the mailer directly.

models/waitlist.rb

class WaitList < ActiveRecord::Base
 before_save {self.email = email.downcase}
 attr_accessible :email

 validates :email, :presence => true, format: { with: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i }

end

controllers/waitlist_controller.rb

class WaitlistsController < ApplicationController
 def create
  @waitlist = Waitlist.new(params[:waitlist])

  if @waitlist.save
   # Tell the ProspectMailer to send an email to us
   WaitlistMailer.waitlist_email(@waitlist).deliver
  end

 end

 private
end

mailer/waitlist.rb

class Waitlist < ActionMailer::Base
 default from: "[email protected]"

 def waitlist_email(waitlist)
  @waitlist = waitlist
  mail( :to => @waitlist.email,
:subject => 'Thanks for signing up!' )
 end
end

views/waitlist/waitlist_email.html.erb

Email text (possibly HTML) for the body of the email sent via the mailer

Thanks for the help!


Solution

  • Your controller should tell the Mailer to send the email.

    In your controller create action, why not just pass the email param to your mailer?

    app/controllers/wait_lists_controller.rb

    class WaitListsController < ApplicationController
      def create
        send_wait_list_email(params[:wait_list][:email])
      end
    
      private
    
      def send_wait_list_email(email)
        WaitListMailer.wait_list_email(email).deliver
      end
    end
    

    app/mailers/wait_list_mailer.rb

    class WaitListMailer < ActionMailer::Base
      def wait_list_email(email)
        mail(to: email, subject: "Thanks for signing up!")
      end
    end
    

    app/views/wait_lists/new.html.erb

    <%= form_for(:wait_list, url: wait_lists_path) do |f| %>
      <%= f.text_field :email, placeholder: "Email" %>
      <%= f.submit "Join" %>
    <% end %>
    

    If you want to do validation on the email, I'd recommend keeping your WaitList model and including ActiveModel::Model — not all models have to inherit from ActiveRecord::Base, only when they need it.

    app/models/wait_list.rb

    class WaitList
      include ActiveModel::Model
      attr_reader :email
    
      def initialize(email)
        @email = email
        post_initialize
      end
    
      validates(
        :email, 
        presence: true, 
        format: { with: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i }
      )
    
      private
    
      def post_initialize
        if email
          email.downcase!
        end
      end
    end
    

    app/controllers/wait_lists_controller.rb

    class WaitListsController < ApplicationController
      def new
        @wait_list = WaitList.new
      end
    
      def create
        @wait_list = WaitList.new(wait_list_params)
        if @wait_list.valid?
          send_wait_list_email(@wait_list)
          # redirect somewhere
        else
          render :new
        end
      end
    
      private
    
      def send_wait_list_email(wait_list)
        WaitListMailer.wait_list_email(wait_list).deliver
      end
    
      def wait_list_params
        params.require(:wait_list).permit(:email)
      end
    end
    

    app/views/wait_lists/new.html.erb

    <%= form_for(@wait_list) do |f| %>
      <%= f.text_field :email, placeholder: "Email" %>
      <%= f.submit "Join" %>
    <% end %>
    

    Hope that helps.

    http://edgeguides.rubyonrails.org/action_mailer_basics.html#calling-the-mailer

    http://api.rubyonrails.org/classes/ActiveModel/Model.html