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