【Rails】Action Mailer

#Action Mailer
Action MailerとはRuby on Railsに標準で組み込まれているメール送信機能です。
Railsからメールが送信されるようになります。

#実装
##Inquiryモデル作成
Action Mailerを実装するために、ユーザーの問い合わせ内容を保存するモデルを作成します。

```
$ bin/rails g model inquiry name:string message:string
~~ 省略 ~~
$ rails db:migrate
```
Inquiryモデルは氏名(name)、メッセージ(message)の属性を持ちます。

##ApplicationMailerを継承するクラスを作成
ApplicationMailerを継承するクラスは`bin/rails generate mailer 任意のメイラー名`で作成できます。

```
$ bin/rails generate mailer inquiry
```

```app/mailers/inquiry_mailer.rb
class InquiryMailer < ApplicationMailer
end
```
##メール宛先、件名等作成
send_mailメソッドをInquiryMailerクラスに記載してメールを送信できるようにします。

```app/mailers/inquiry_mailer.rb
def send_mail(inquiry)
  @inquiry = inquiry
  mail(
    from: 'system@example.com',
    to:   'manager@example.com',
    subject: 'お問い合わせ通知'
  )
end
```
それぞれ下記のように設定されています。
・`from :`　→　　送信元のメールアドレス
・`to :`　→　送信先のメールアドレス
・`subject :`　→　件名
他には下記があります。
・`cc :`　→　CCのメールアドレス
・`bcc :`　→　BCCのメースアドレス

##メール本文のレイアウト
メール本文のレイアウトを作成するためには命名規則に従ってerbファイルを作成します。
新規で`app/views/inquiry_mailer/send_mail.text.erb`ファイルを作成しメール内容を記載していきます。

```erb:app/views/inquiry_mailer/send_mail.text.erb
<%= @inquiry.name %> 様 から問い合わせがありました。
・お問い合わせ内容
<%= @inquiry.message %>
```
このようにerbのタグを使用してコードを記載することが可能です。
##メールをプレビューで確認
メール本文のレイアウトを確認するためにAction Mailerにはプレビュー機能があります。

先ほど`generateコマンド`で生成した`ActionMailer::Preview`を継承した`inquiry_mailer_preview.rb`があるので、こちらにコーティングしていきます。

```test/mailers/previews/inquiry_mailer_preview.rb
# Preview all emails at http://localhost:3000/rails/mailers/inquiry_mailer
class InquiryMailerPreview < ActionMailer::Preview
  def inquiry
     inquiry = Inquiry.new(name: "侍 太郎", message: "問い合わせメッセージ")
    
     InquiryMailer.send_mail(inquiry)
   end
end
```
実際に確認をしみましょう。
`rails s`でサーバを起動し`http://ホスト名:3000/rails/mailers/inquiry_mailer`にアクセスすると
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/597913/e650c977-e0f0-f6df-807a-26e205f34ed4.png)
このように表示されるので、`・ inquiry`をクリックすると
※inquiryのリンクは、InquiryMailerPreviewクラスに作成したinquiryメソッドに対応して表示されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/597913/caec745a-d7fb-da78-03eb-cf319eb3ff69.png)
が表示されて、メール本文のレイアウトを確認することができます。
こちらメールが送信されることはないので何度でも確認することができます。

##メールサーバの設定
実際にメール送信を行うために設定をしていきます。
なお、Gmailでは２段階認証等があるためセキュリティの状態によっては送信できない可能性があります。

```config/environments/development.rb
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
 address:              'smtp.gmail.com',
 port:                  587,
 domain:               'gmail.com',
 user_name:            '<gmailのメールアドレス>',
 password:             '<gmailのパスワード>',
 authentication:       'plain',
 enable_starttls_auto:  true
}
```
上記のようにメールサーバの設定をコーディングします。

##メール送信
メールを送信するためにdeliver_nowメソッドを使用する。
本記事のサンプルプログラムで実行するためには、`InquiryMailer.send_mail(モデル変数).deliver_now`で実行します。

コントローラに設定すれば実行できますが今回はコンソールから実行します。
`app/mailers/inquiry_mailer.rb`の`to :`や`from :`を変更し実行します。

```
$ bin/rails c
    ~~ 省略 ~~ 
irb(main):001:0> inquiry = Inquiry.new(name: "侍 太郎", message: "問い合わせメッセージ")
irb(main):002:0> InquiryMailer.send_mail(inquiry).deliver_now
```
実行後に設定したメールアドレスにメールが送信されていれば成功です。

#応用的なメール送信方法
##HTML形式なレイアウトのメール送信
Action MailerでHTML形式のメールを送信するためには、`app/views/メイラー名_mailer/メイラークラスのメソッド名.html.erb`とファイル名を記載しメール本文もHTML形式で記載します。

```app/views/inquiry_mailer/send_mail.html.erb：
<!DOCTYPE html>
<html>
  <head>
    <meta content='text/html; charset=UTF-8' http-equiv='Content-Type' />
  </head>
  <body>
    <h1><%= @inquiry.name %> 様 から問い合わせがありました。</h1>
    <p>・お問い合わせ内容</p>
    <p><%= @inquiry.message %></p>
  </body>
</html>
```
プレビュー機能でレイアウトを確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/597913/4af1fe33-542f-c0c5-f19c-07868ffd00f4.png)
HTML形式のメールレイアウトであることを確認できました。

また下記の２つのようにテキストメールとHTMLメールの２つが存在する場合はRailsはマルチパートメールを自動生成して送信します。
・app/views/メイラー名_mailer/メイラークラスのメソッド名.text.erb
・app/views/メイラー名_mailer/メイラークラスのメソッド名.html.erb

マルチパートメールとはテキスト、HTMLメールの両方を送信してメールクライアント側で自動判定してメールを表示する仕組みです。

##添付ファイル付きのメール送信
添付ファイルをメールに付ける機能を追加するには下記をメイラークラスに追記します。
`attachments[添付ファイル名] = 添付するファイルデータ`

```app/mailers/inquiry_mailer.rb
class InquiryMailer < ApplicationMailer
　　def send_mail(inquiry)
   @inquiry = inquiry
   # 追記
   attachments['sample.jpg'] = ..File.read(‘./tmp/sample.jpg')  
   mail(
     from: 'system@example.com',
     to:   'manager@example.com',
     subject: 'お問い合わせ通知'
   )
  end
end
```
画像ファイルにsample.jpgを添付しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/597913/e678ff6e-7ef1-48f6-9a3d-e52511fe452f.png)
プレビューではこのようになっています。