[Ruby on Rails] Creating an inquiry form

Target

Create an inquiry form like this. This time it is a method to send to gmail in the development environment. 問い合わせ.png

Development environment

ruby 2.5.7 Rails 5.2.4.3 OS: macOS Catalina

Premise

bootstrap4 installed

[Ruby on Rails] How to write enum in Japanese Used to select the subject of your inquiry. This is where _i18n is used.

flow

1 Create and edit mailer 2 Creating a table 3 Edit config / environments / development.rb 4 Setting environment variables 5 Creating a controller 6 routing edit 7 Edit view 8 Allow access to insecure apps with your google account

Create and edit mailer

Terminal


$ rails g mailer ContactMailer

Specify the destination and subject. ENV ['TOMAIL'] will be set later.

app/mailers/thanks_mailer.rb


class ContactMailer < ApplicationMailer
  def send_mail(contact)
    @contact = contact
    mail to:   ENV['TOMAIL'], subject: '【Contact Us】' + @contact.subject_i18n
  end
end

Creating a table

Terminal


$ rails g model Contact

Add the columns you need. I will explain the enum settings in the next article.

db/migrate/xxxxxxxxxxxxx_create_contacts.rb


class CreateContacts < ActiveRecord::Migration[5.2]
  def change
    create_table :contacts do |t|
      t.string :name, null: false
      t.string :email, null: false
      t.string :phone_number, null: false
      t.integer :subject, default: 0, null: false
      t.text :message, null: false

      t.timestamps
    end
  end
end

Editing config / environments / development.rb

config/enviroments/development.rb



...

config.action_mailer.raise_delivery_errors = false 
↓ Change to true
config.action_mailer.raise_delivery_errors = true

...

config.action_mailer.delivery_method = :smtp
  config.action_mailer.smtp_settings = {
      port: 587,
      address: 'smtp.gmail.com',
      domain: 'smtp.gmail.com',
      user_name: ENV['SMTP_USERNAME'],
      password: ENV['SMTP_PASSWORD'],
      enable_starttls_auto: true
  }
end

Setting environment variables

Don't upload your address and password on GitHub this time Use gem "dotenv-rails".

Gemfile


gem "dotenv-rails"

Terminal


$ bundle install

Then create an .env file in the same hierarchy as the Gemfile

.env


TOMAIL=Destination address

SMTP_USERNAME=Sender's gmail address
SMTP_PASSWORD=Sender's gmail address password
Failure story [SMTP_USERNAME] When I first tried to set SMTP_USERNAME to MAIL, I got an error no matter how many times I tried. Therefore, it may be better to write it like this when setting. I would like to update it again after studying the naming convention.

Add the following to the bottom of the .gitignore file.

.gitignore


/.env

Creating a controller

Terminal


$ rails g controller contacts

app/controllers/contacts_controller.rb


class Public::ContactsController < ApplicationController
  def new
    @contact = Contact.new
  end
  
  #If you want to create a confirmation screen, you should write something like this.
  #Receive input from new action
  #When the submit button is pressed, the create action is executed.
  def confirm
    @contact = Contact.new(contact_params)
    if @contact.invalid?
      render :new
    end
  end
 
  #If there is an error in the input contents,
  #I think it is natural to return to the previous page while retaining the input contents,
  #This is possible by defining a back action.
  def back
    @contact = Contact.new(contact_params)
    render :new
  end

  #It is the action that is actually sent.
  #This is the first time you save your input.
  #For security reasons, you may want to delete the input contents after a certain period of time.
  def create
    @contact = Contact.new(contact_params)
    if @contact.save
      ContactMailer.send_mail(@contact).deliver_now
      redirect_to done_path
    else
      render :new
    end
  end

  #Please use when using the transmission completion screen.
  def done
  end

  private

  def contact_params
    params.require(:contact)
          .permit(:email,
                  :name,
                  :phone_number,
                  :subject,
                  :message
                 )
  end
end

routing edit

config/routes


resources :contacts, only: [:new, :create]
post 'contacts/confirm', to: 'contacts#confirm', as: 'confirm'
post 'contacts/back', to: 'contacts#back', as: 'back'
get 'done', to: 'contacts#done', as: 'done'

edit view

Under app / views / contact_mailer send_mail.html.erb Please create send_text.html.erb.

  • I don't know why I will create two, so I would like to entrust it to myself in the future. .. .. Please fill in the same content

erb:app/views/contact_mailer/send_mail.html.erb,send_text.html.erb


<%= @contact.name %>I received an inquiry from Mr.<br>
【Tel】:<%= @contact.phone_number %><br>
【Mail】:<%= @contact.email %><br>
[Requirements]:<%= @contact.subject_i18n %><br>
【Content of inquiry】<br>
<span style="white-space: pre-wrap;"><%= @contact.message %></span>

We will create the actual input form.

  • Describe only the name and message.

erb:app/views/contacts/new.html.erb



<%= form_for(@contact, url: confirm_path) do |f| %>
  <div class="form-group">
    <%= f.label :name, 'name*' %>
    <%= f.text_field :name, autofocus: true, class: 'form-control' %>
  </div>
    
  <div class="form-group">
    <%= f.label :message, 'message*' %>
    <%= f.text_area :message, size: '10x10', class: 'form-control' %>
  </div>

  <div>
    <%= f.submit 'Confirm input' %>
  </div>
<% end %>

Write the code to return to the input screen from the confirmation screen.

  • Describe only the name and message.

erb:app/views/contacts/confirm.html.erb



<table>
  <tbody>
    <tr>
      <td class="text-center" style="width: 30%;">name</td>
      <td><%= @contact.name %></td>
    </tr>
    <tr>
      <td class="text-center">message</td>
      <td style="white-space: pre-wrap;"><%= @contact.message %></td>
    </tr>
  </tbody>
</table>

<%= form_for(@contact) do |f| %>
  <%= f.hidden_field :name %>
  <%= f.hidden_field :email %>
  <%= f.hidden_field :phone_number %>
  <%= f.hidden_field :subject %>
  <%= f.hidden_field :message %>
  <div><%= f.submit 'Send' %></div>
<% end %>
<%= form_for @contact, url: back_path do |f| %>
  <%= f.hidden_field :name %>
  <%= f.hidden_field :email %>
  <%= f.hidden_field :phone_number %>
  <%= f.hidden_field :subject %>
  <%= f.hidden_field :message %>
  <div><%= f.submit 'Returns to the input screen' %></div>
<% end %>
Supplement [<% = @ contact.name%>] Because I skipped to the confirm action in the form of the new screen In params, you can create a state where @contact has a value. Therefore, it can be displayed without saving.
Supplement [Send] Although it is displayed by @contact, it has not been saved. If you skip to the create action as it is, params will be thrown without being saved. So I use f.hidden_field, reassign params to each, and skip to create.
Supplement [Return to input screen] This is the same reason as sending, so please check the above Although it is displayed by @contact, it has not been saved.

Allow access to insecure apps with your google account

How to enable access to Google insecure apps This article was easy to understand, so please refer to it.

reference

-Rails and email sending this and that -How to use environment variables in Ruby On Rails * English -Simple implementation of inquiry function -How to create an inquiry form with rails and send it to your email address

Summary

Because it deals with personal addresses and phone numbers I think it is essential to delete the privacy policy and information on a regular basis. However, I think that being able to automatically send emails to the other party is a high priority in various cases. You may want to understand it well.

Also, on twitter, technologies and ideas that are not uploaded to Qiita are also uploaded, so I would be grateful if you could follow me. Click here for details https://twitter.com/japwork

Recommended Posts