Railsでお問い合わせフォームを作成【Action Mailer】letter_opener

Rails-contacts-us

クリスマスが終わり正月が過ぎ、初詣にも行き、ようやく行事的に落ち着きました。そんな中早速胃腸炎でダウンしましたが。(苦笑)

本業はWebエンジニアではないのですが、Railsの開発をしつつその開発段階で困った事に対しての備忘録として、ブログの記事を書いたり、Qiitaに投稿したりしています。

今回ちょうどお問い合わせ機能をローカルでの実装を兼ねて制作していたので、備忘録のついでにご紹介致します。

お問い合わせ機能は初心者でもできる機能

さて今回はRailsで問合せ機能を追加する方法について紹介したいと思います。
ただ便利な世の中になってきた為、Googleが提供しているフォームでも間に合うのも確かです。

こちらの記事をご参照ください

Googleフォーム

お問い合わせ機能 modelはContact

RailsにはActin Mailerという送信する機能があり、便利にもViewや Controllerの様に扱う事が出来ます。

$ rails g scaffold Contact name:string email:string content:text
MEMO
今回はscaffoldでModel Controller viewを生成して制作の時短を測ります。
注意
scaffoldはモデル、コントローラー、ビューを一度に生成してくれる便利なgeneraterですが、便利な故railsの体系な部分を腹落ちするほどの理解を省略しがちになります。プログラミング初心者はRailsの流れをよく学びましょう。

Railsの流れを銀行の流れで例える

今回せっかくscaffoldでジェネレートするので、Railsの流れを腹落ちできる様、この記事に置いて残しておきたい。

私がRailsを学ばさせて頂いたDive Into CodeではRailsの体系的な流れを銀行の流れの様に掴むと、学びやすいと教わりました。

参考までにこちらの記事をご参考ください。

Railsの処理の流れを理解しよう

Railsでお問いわせ機能作成【contact form】

さてRailsで実際にお問い合わせ機能を作成してみましょう。
プログラミング初心者でも実装出来ますし、おそらくどのプログラミングスクールからも学ぶ題材の一つだと思います。

Scaffoldで一括ジェネレート

先ほどのコマンドをします。

$ rails g scaffold Contact name:string email:string content:text

そうするとmodel controller viewファイルそして、マイグレーションファイルまでジェネレートされます。

 invoke  active_record
      create    db/migrate/20200111177877_create_contacts.rb
      create    app/models/contact.rb
      invoke    test_unit
      create      test/models/contact_test.rb
      create      test/fixtures/contacts.yml
      invoke  resource_route
       route    resources :contacts
      invoke  scaffold_controller
      create    app/controllers/contacts_controller.rb
      invoke    erb
      create      app/views/contacts
      create      app/views/contacts/index.html.erb
      create      app/views/contacts/edit.html.erb
      create      app/views/contacts/show.html.erb
      create      app/views/contacts/new.html.erb
      create      app/views/contacts/_form.html.erb
      invoke    test_unit
      create      test/controllers/contacts_controller_test.rb
      create      test/system/contacts_test.rb
      invoke    helper
      create      app/helpers/contacts_helper.rb
      invoke      test_unit
      invoke    jbuilder
      create      app/views/contacts/index.json.jbuilder
      create      app/views/contacts/show.json.jbuilder
      create      app/views/contacts/_contact.json.jbuilder
      invoke  assets
      invoke    scss
      create      app/assets/stylesheets/contacts.scss
      invoke  scss
      create    app/assets/stylesheets/scaffolds.scss
注意
このコマンドの後にマイグレートしなければ、下記のエラーが発生します。
Started GET "/contact" for ::1 at 2020-01-11 22:41:01 +0900
   (9.1ms)  SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC

ActiveRecord::PendingMigrationError - Migrations are pending. To resolve this issue, run:

        rails db:migrate RAILS_ENV=development

:

Started POST "/__better_errors/5e8da7d94d079026/variables" for ::1 at 2020-01-11 22:41:01 +0900

$rails db:migrate
rails db:migrate
== 20200111177877 CreateContacts: migrating ===================================
-- create_table(:contacts)
   -> 0.0950s
== 20200111177877 CreateContacts: migrated (0.0951s) ==========================

ここでローカル環境にて、contacts/newにアクセスしてみましょう。

この様な表示が返ってくれば成功ですね。

Action Mailerの生成

Action Mailerをジェネレーターで生成します。

%bin/rails g mailer class名 メソッド名

Classはcontact,メソッドはメーラーなので、

%bin/rails g mailer ContactMailer

コマンドを実行すると、

%bin/rials g mailer ContactMailer
 create  app/mailers/contact_mailer.rb
      invoke  erb
      create    app/views/contact_mailer
      invoke  test_unit
      create    test/mailers/contact_mailer_test.rb
      create    test/mailers/previews/contact_mailer_preview.rb

メールの宛先や件名の記載指定

送信機能を実装する為に、app/mailers/contact_mailer.rb内でコードを記載していきます。

class ContactMailer < ApplicationMailer
  def contact_mail(contact)
    @contact = contact
    mail to:"自信のメールアドレス@xxx.com",subject: "confirmation"
  end
end
@contact = contact

@contact = contact にする事で情報をviewに引き渡す事が出来ます。なおmail to:の部分はご自身のメールアドレスを。

MEMO
メール送信するためのApplicationMailerを継承するクラスで今回のContactMailerはApplicationMailerを継承しています。Rails特有の継承ですが、ApplicationMailerもActionMailer::Baseを継承しております。

mailメソッドのオプション

to:の送り先やsubject:の件名のオプション以外に、一般的なメールの機能のオプションがあります。

MailメソッドのオプションMailメソッドオプションの概要
from:送信元ですね。
cc:CCで、送り先とは直接関係はないが少し知っておいてねという人達の宛先
bcc:ToとCCには知る事はなく、こっそり伝えたい場合の宛先。

これらは通常のメール機能と変わりなく機能として加える事が出来ます。今回ここではto:とsubject:のみお伝え致します。

メール送信機能の実装【ローカル環境内】

scaffoldで一括で生成されたモデルやコントローラー、そしてジェネレートされたAction Mailerを元により一層実装できる様に近づけます。

Viewファイルにて本文内を作成

app/views/生成したメイラー名_mailerの配下にメイラークラスのメソッド.html.erbを作成します。

app/views/contact_mailer/contact_mail.html.erb

<h1>Successfully Done.Thank you for contacting us.</h1>

<h3>name: <%= @contact.name %></h3>

<h3>お問い合わせ内容の確認</h3>

<p>content: <%= @contact.content %></p>
MEMO
@contact.メソッドで、app/mailers/contact_mailer.rbで定義したのを呼び出す事が出来ます。

contacts_controllerのコーディング

class ContactsController < ApplicationController
  before_action :set_contact, only: [:show, :edit, :update, :destroy]

  def index
    @contacts = Contact.all
  end

  def show
  end

  def new
    @contact = Contact.new
  end

  def create
    @contact = Contact.new(contact_params)
    if @contact.save
      ContactMailer.contact_mail(@contact).deliver
      redirect_to contacts_path,notice: 'Contact was successfully created.'
    end
  end

  def edit
  end

  def update
    respond_to do |format|
      if @contact.update(contact_params)
        format.html { redirect_to @contact, notice: 'Contact was successfully updated.' }
        format.json { render :show, status: :ok, location: @contact }
      else
        format.html { render :edit }
        format.json { render json: @contact.errors, status: :unprocessable_entity }
      end
    end
  end

  def destroy
    @contact.destroy
    respond_to do |format|
      format.html { redirect_to contacts_url, notice: 'Contact was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_contact
      @contact = Contact.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def contact_params
      params.require(:contact).permit(:name, :email, :content)
    end
end
注意
コードはほぼデフォルトなので、必要に応じて書き換えてください。

大事なのは、

def create
    @contact = Contact.new(contact_params)
    if @contact.save
      ContactMailer.contact_mail(@contact).deliver
      redirect_to contacts_path,notice: 'Contact was successfully created.'
    end

gemで開発環境の送信メールを実装準備【letter_opener_web】

開発環境すなわちdevelopment内で送信メールの確認の実装をする事が出来ます。よくよくはこれを本番環境内にも実装をしていきます。

gem “letter_opener_web”の追加

gemfileにて”letter_opner_web”を追加します。
その際は、groupのdevelopment内で追加。

group :development do
  # Access an interactive console on exception pages or by calling 'console' anywhere in the code.
  gem 'web-console', '>= 3.3.0'
  gem 'listen', '>= 3.0.5', '< 3.2'
  # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
  gem 'spring'
  gem 'spring-watcher-listen', '~> 2.0.0'
  gem 'letter_opener_web'
end
%bundle install

routingの追記

routingにて、”mount LetterOpenerWeb::Engine, at: “/letter_opener” if Rails.env.development?”を追記してあげます。

Rails.application.routes.draw do
  mount LetterOpenerWeb::Engine, at: "/letter_opener" if Rails.env.development?
  resources :contacts
  devise_for :users
  resources :users
  
end

configファイルの設定でgemをletter_opener_webが使用できる様に

 # Don't care if the mailer can't send.
  config.action_mailer.raise_delivery_errors = false

  config.action_mailer.perform_caching = false

  config.action_mailer.default_url_options = { host: 'localhost:3000' }
  config.action_mailer.delivery_method = :letter_opener_web
注意
config系のファイルを編集した場合、ローカルサーバーを一旦切り、再接続しないと編集内容は反映しません。
注意
cloud9を使用している場合は違えますので、ご注意ください

メールが届くか実装してみる

ここまで来れば後は実装するだけ。
あくまでも開発環境内の実装ですが、プログラミング初心者には持って来いの良いトレーニングになります。

http://localhost:3000/contacts/newを開く

localhost:300/contacts/newにアクセスします。

http://localhost:3000/contacts/new
http://localhost:3000/contacts/new

無事に上記の表示が出れば今の所うまくいっております。

実際に問合せてみる

実際にpostして見ましょう!

Name、Email、本文を入力してcreateします。

ターミナルでも挙動を確認します。

localhost:3000/letter_openerにアクセス

投稿したinboxを確認する為に、localhost:3000/letter_openerにアクセスします。

この様に表示されていれば完了です!

Rails6においての過去記事

最近ですがRails6となり、記事を新しく更新しております。
備忘録として記事を書いて残しつつ、参考にして頂けましたら幸いです。

今後ともどうぞ宜しくお願い致します。

4児パパ

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です