Search code examples
ruby-on-railsemailmail-form

Email notification (to user) after mail form on Rails


I am new to Rails and I would like to make a "subscribe" feature on my app.

I did manage to get a notification (via email) whenever someone subscribes my website. What I want to do now is send a notification to the user giving my thanks.

What I have:

/models/contact.rb

class Contact < MailForm::Base
  attribute :name
  attribute :email,     :validate => /\A([\w\.%\+\-]+)@([\w\-]+\.)+([\w]{2,})\z/i
  attribute :message
  attribute :nickname,  :captcha  => true
  def headers
    {
      :subject => "New Subscription:",
      :to => "[email protected]",
      :from => "[email protected]"
    }
  end
end

/controllers/contacts_controller.rb

class ContactsController < ApplicationController
  def create
      @contact = Contact.new(params[:contact])
      @contact.request = request
      if @contact.deliver
        redirect_to(:back)
      else
        #TODO fail notification
        redirect_to(:back)
      end
  end
end

What I tried:

  • Using an ActionMailer::Base class to send emails but I'm not able to retrive params[:contact][:email] from the form and therefore cannot email a response
  • Send multiple emails using mailform, but I did not achieve that

My problem here is that I do not have a user model, nor do I need one since there will be no storage on this app.


Solution

  • If I can suggest is that you generate Contact model from ApplicationRecord and store all people that subscribed to your website. Then you can use ActiveJob to send them Thank you notice. And Then you can also add notification to your email to get notified when someone applied to your websites.

    Here are some of the changes:

    bin/rails g model Contact name:string email:string message:text is_sent:boolean
    

    Note that I added a boolean filed to indicate that message has been sent but you can leave this.

    So instead of using model.contact and inheriting from MailForm::Base I am creating a contact model that will store your contacts to database. I think ti is a good practice since you can have a reference of these users later and potentially create user account from them or do something else useful.

    Inside your controller when you save contact record you can initiate sending of emails using ActiveJob or use default Mailer to send emails. So you will have something like this inside your controller

    def create
      @contact = Contact.create(contact_params)
      if @contact.persisted?
        ContactMailer.say_thank_you(@contact).deliver_now
        ContactMailer.notify_webmaster(@contact).deliver_now
        # do the success redirect...
      else
        # do the failed redirect...handle error etc
      end
    

    So you would first save the record to database check if it is saved and then notify user and webmaster with different email template. For generating action email method that I used in example say_thank_you and notify_webmaster please refer to the Getting started guides.

    http://guides.rubyonrails.org/action_mailer_basics.html

    Since you are new to rails I assumed that you are familiar with creating migrations and permitting params contact_params....params.require(:contact).permit(:name.... - you can use default scaffold and check code generated code inside controller.

    In my above example I am using is_sent a boolean property which I set to false by default. Then once ActionMailer sends email I update this field or retry later. Just to know which people received email but this is optional.

    Hope it helps.