<!-Description the beginning and outline-> Ruby on Rails 5 Quick Learning Practice Guide that can be used in the field is used for input and is posted as output. The sample is a task management app. In this post, we will implement a function to send an email saying "○○ task has been registered" when the user registers the task.
<!-Edit title and anchor name->
Mailer is ActionMailer, which is a function to send emails installed in rails. Just as the controller passes the information to the template and outputs the screen, the Mailer also passes the information to the template and sends an email. First, create the TaskMailer to be implemented this time. Execute the following command.
rails g mailer TaskMailer
The previous command will create a file called app/mailer/task_mailer.rb. Define the method "creation_email" of the email to be sent this time.
app/mailer/task_mailer.rb
def creation_email(task)
  @task = task
  mail(
    subject: 'Task creation completion email',
    to: '[email protected]',
    from: '[email protected]'
  )
end
When calling this method, ask the added task to be passed as an argument. Since the contents of task are displayed as a template, they are stored in instance variables.
Next, create a template. Depending on the user's reception environment, it may not be possible to display html format emails. Create two types of files because the text format file is created together and sent together with the html format.
app/views/task_mailer/creation_email.html.slim
|I have created the following tasks
ul
  li
    |name:
    = @task.name
  li
    |detailed explanation
    = simple_format(@task.description)
app/views/task_mailer/creation_email.text.slim
|I have created the following tasks
= "\n"
|name:
= @task.name
= "\n"
|detailed explanation
= "\n"
= @task.description
At this point, all you have to do is describe the process to send! This time, in order to send an email together with the task save process, write the send process in the create method of tasks_controller.
app/controllers/tasks_controller.rb
Abbreviation
    if @task.save
      TaskMailer.creation_email(@task).deliver_now
      SampleJob.perform_later
      logger.debug "task:「#{@task.attributes.inspect}Was registered"
      redirect_to tasks_url, notice: "task"#{@task.name}Has been registered."
    else
      render :new
    end
Abbreviation
deliver_now is literally an immediate instruction. If you want to send an email in 5 minutes, use deliver_later (wait: 5 minutes).
Was the email sent and is the content of the email as intended? To check this, we use a gem called "mailcatcher".
gem install mailcatcher
Execute the above command and write the following in the rails configuration file.
config/environments/development.rb
  # Don't care if the mailer can't send.
  config.action_mailer.raise_delivery_errors = false
  #Add the following two lines
  config.action_mailer.delivery_method = :smtp
  config.action_mailer.smtp_settings = { address: '127.0.0.1', port: 1025}
The above is the setting of the development environment, but the setting of the production environment is described in procedure.rb.
After completing the description of the configuration file, restart the server. The confirmation procedure is
--Run mailcatcher in the terminal
--Access http://127.0.0.1:1080/ after executing the mail sending flow
Then, you can check the sent mail.
First, create a directory for mailer's Spec.
mkdir spec/mailers
Create task_mailer_spec.rb in the created folder and write as follows.
spec/mailers/task_mailer_spec.rb
require 'rails_helper'
describe TaskMailer, type: :mailer do
end
Now that the framework is complete, let's actually write the test.
spec/mailers/task_mailer_spec.rb
require "rails_helper"
RSpec.describe TaskMailer, type: :mailer do
  let(:task){FactoryBot.create(:task, name: 'Write Mailer Spec', description: 'Check the content of the email you sent')}
  let(:text_body) do
    part = mail.body.parts.detect{|part| part.content_type == 'text/plain; charset=UTF-8'}
    part.body.raw_source
  end
  let(:html_body) do
    part = mail.body.parts.detect{|part| part.content_type == 'text/html; charset=UTF-8'}
    part.body.raw_source
  end
  describe '#creation_email' do
    let(:mail){TaskMailer.creation_email(task)}
    it "The expected email is being generated" do
      expect(mail.subject).to eq('Task creation completion email')
      expect(mail.to).to eq(['[email protected]'])
      expect(mail.from).to eq(['[email protected]'])
      expect(text_body).to match('I have created the following tasks')
      expect(text_body).to match('Write Mailer Spec')
      expect(text_body).to match('Check the content of the email you sent')
      expect(html_body).to match('I have created the following tasks')
      expect(html_body).to match('Write Mailer Spec')
      expect(html_body).to match('Check the content of the email you sent')
    end
  end
end
Execute the following command and check if it passes.
bundle exec rspec spec/mailers/task_mailer_spec.rb
-Ruby on Rails 5 Quick Learning Practice Guide that can be used in the field
Recommended Posts