Creating a portfolio for job change activities. Since we have implemented the inquiry function from the user this time, we will describe it for memorandum and review.
Ruby on Rails'6.0.0' Ruby'2.6.5'
config/routes.rb
resource :contacts, only: [:new, :create] do
 get "/thanks" => "contacts#thanks"
end
This time, after the user sends an inquiry, a page like "Thank you for your inquiry!" Is displayed.
After creating a model with the rails g model contact command, describe the migration file and so on.
db/migrate/20201204073627_create_contacts.rb
class CreateContacts < ActiveRecord::Migration[6.0]
  def change
    create_table :contacts do |t|
      t.string :name, null: false
      t.string :email, null: false
      t.text :content, null: false
      t.timestamps
    end
  end
end
This time, I specified the name, the email address for reply, and the content of the inquiry. Then run the rails db: migrate command.
app/models/contact.rb
class Contact < ApplicationRecord
  validates :name, :email, :content, presence: true
end
Set validation so that your name, email address, and inquiry content cannot be saved if they are empty.
This time, I would like to make the function so that when an inquiry is sent from a user, the content will be sent to the administrator by e-mail. So I used ActionMailer. First, run the rails g mailer Contact Mailer command. Then, the following file will be generated, so if you receive an inquiry, we will send an email to the administrator.
app/mailers/contact_mailer.rb
class ContactMailer < ApplicationMailer
  def contact_mail(contact)
    @contact = contact
    mail to: '(Administrator's email address)@gmail.com', subject: '(Email title)'
  end
end
Next, since a new view file is generated, we will describe the body of the email.
ruby:app/views/contact_mailer/contact_mail.html.erb
<p>User name:<%= @contact.name %></p>
<p>mail address:<%= @contact.email %></p>
<p>Content of inquiry:<%= @contact.content %></p>
Now let's describe the controller.
app/controllers/contacts_controller.rb
class ContactsController < ApplicationController
  def new
    @contact = Contact.new
  end
  def create
    @contact = Contact.new(contact_params)
    if @contact.save
      ContactMailer.contact_mail(@contact).deliver
      redirect_to thanks_contacts_path
    else
      render :new
    end
  end
  def thanks
  end
  private
  def contact_params
    params.require(:contact).permit(:name, :email, :content)
  end
end
As a result, when the create action is called and the inquiry is saved successfully, the mail sending process can also be set to start.
I will describe the view file of the inquiry.
ruby:app/views/contacts/new.html.erb
<div class="container">
  <div class="row">
    <div class="offset-sm-2 col-sm-8 offset-sm-2">
    <%= form_with model: @contact, local: true do |f| %>
      <h5 class='form-header-text text-center'><i class="far fa-paper-plane fa-2x my-orange"></i>Contact Us</h5>
  <%= render 'layouts/error_messages', model: f.object %>
      <div class="form-group">
        <div class='form-text-wrap'>
          <label class="form-text" for="name">name</label>
          <span class="badge badge-danger">Mandatory</span>
        </div>
        <div class='input-name-wrap'>
          <%= f.text_field :name, class:"input-name", id:"name", placeholder:"Example)Taro Tanaka" %>
        </div>
      </div>
      <div class="form-group">
        <div class='form-text-wrap'>
          <label class="form-text" for="email">mail address</label>
          <span class="badge badge-danger">Mandatory</span>
        </div>
        <%= f.email_field :email, class:"input-default", id:"email", placeholder:"Either PC or mobile is acceptable", autofocus: true %>
      </div>
      <div class="form-group">
        <div class='form-text-wrap'>
          <label class="form-text" for="content">Contents</label>
          <span class="badge badge-danger">Mandatory</span>
        </div>
        <%= f.text_area :content, class:"article-input-default", id:"content", autofocus: true %>
      </div>
 
      <div class='contact-btn text-center'>
        <%= f.submit "Send" ,class:"btn btn-outline-danger w-50" %>
      </div>
    <% end %>
    </div>
  </div>
</div>
ruby:app/views/contacts/thanks.html.erb
<div class="container">
  <div class="row">
    <div class="offset-sm-2 col-sm-8 offset-sm-2">
      <h5 class='header-text text-center'><i class="far fa-smile fa-lg my-orange"></i>Thank you for your inquiry</h5>
      <%= link_to 'Go back to the top page', root_path %>
    </div>
  </div>
</div>
Finally, I set up Gmail to be used with the address this time.
config/environments/development.rb
(Omission)
  config.action_mailer.perform_deliveries = true
  config.action_mailer.raise_delivery_errors = true
  config.action_mailer.delivery_method = :smtp
  config.action_mailer.smtp_settings = {
    address: 'smtp.gmail.com',
    domain: 'gmail.com',
    port: 587,
    user_name: '(Administrator email address)@gmail.com',
    password: ENV["GMAIL_KEY"],
    authentication: 'plain',
    enable_starttls_auto: true
  }
(Omission)
I think that other settings have already been described, so I described them in between. If the Gmail password goes up on GitHub, it will be a big deal, so set the environment variable. I think there are many ways to set it, but I used the vim command to set it in a ".zshrc" file.
Terminal
% vim ~/.zshrc
Open the file with the above command, put it in insert mode, and then write it.
.zshrc file
(Omitted)
export GMAIL_KEY = "Gmail password" 
(Omitted)
The setting is completed here!
As a bonus, I also implemented the test code using Rspec.
FactoryBot
spec/factories/contacts.rb
FactoryBot.define do
  factory :contact do
    name { Faker::Name.name }
    email { Faker::Internet.email }
    content { Faker::Lorem.sentence }
  end
end
spec/models/contact_spec.rb
require 'rails_helper'
RSpec.describe Contact, type: :model do
  before do
    @contact = FactoryBot.build(:contact)
  end
  describe 'Send an inquiry' do
    context 'If you can send an inquiry' do
      it 'You can post if all the elements are present' do
        expect(@contact).to be_valid
      end
    end
    context 'If you cannot send your inquiry' do
      it 'Cannot be sent if name is empty' do
        @contact.name = nil
        @contact.valid?
        expect(@contact.errors.full_messages).to include('Please enter your name')
      end
      it 'Email cannot be sent empty' do
        @contact.email = nil
        @contact.valid?
        expect(@contact.errors.full_messages).to include('Please enter your e-mail address')
      end
      it 'Cannot send if content is empty' do
        @contact.content = nil
        @contact.valid?
        expect(@contact.errors.full_messages).to include('Please enter your inquiry')
      end
    end
  end
end
spec/system/contacts_spec.rb
require 'rails_helper'
RSpec.describe 'Send inquiry', type: :system do
  before do
    @contact = FactoryBot.build(:contact)
  end
  context 'When you can send an inquiry' do
    it 'If you enter the correct information, you can send an inquiry' do
      visit root_path
      expect(page).to have_content('Contact Us')
      visit new_contacts_path
      fill_in 'name', with: @contact.name
      fill_in 'mail address', with: @contact.email
      fill_in 'Contents', with: @contact.content
      expect do
        find('input[name="commit"]').click
      end.to change { Contact.count }.by(1)
      expect(current_path).to eq thanks_contacts_path
      click_link 'Go back to the top page'
      expect(current_path).to eq root_path
    end
  end
  context 'When you cannot send an inquiry' do
    it 'Inquiries cannot be sent without entering the correct information' do
      visit root_path
      expect(page).to have_content('Contact Us')
      visit new_contacts_path
      fill_in 'name', with: ''
      fill_in 'mail address', with: ''
      fill_in 'Contents', with: ''
      expect do
        find('input[name="commit"]').click
      end.to change { Contact.count }.by(0)
      expect(current_path).to eq contacts_path
    end
  end
end
https://qiita.com/mmdrdr/items/9c5dd4ca886f034fb0ef https://qiita.com/hirotakasasaki/items/ec2ca5c611ed69b5e85e
I referred to the above article. Thank you very much.
I'd like to test sending emails, so I'll check it out! !! Please point out any mistakes.
Recommended Posts