管理画面からメール送信(ActiveAdminでのmailer実装)


#ActiveAdminでのmailer実装
ユーザーに管理画面(ActiveAdmin)からメールを送りたい。
[公式ページ]
(http://activeadmin.info/)
に詳細がなかったため、メモ。

#前提

- バリデーションが全てフォームで行う。
- ユーザ選択されていない場合は、ユーザータブへリダイレクトする。
- 選択されたユーザーのuser_idsを貰い、Form側でuser_idsからusersを生成する。
- queueは使わず

#Admin側
##1.User
batch_action追加

```app/admin/user.rb
ActiveAdmin.register User do
  before_filter :paging_set

  batch_action :set_users do |ids|
    redirect_to admin_mailer_path(user_ids: ids)
  end

 # 全選択したいので、ページングしない
  controller do　
    def paging_set
      @per_page = 99_999_999
    end
  end

```

##2.mailer


```app/admin/mailer.rb
ActiveAdmin.register_page 'Mailer' do
  # 5,6のmailerとformをインクルード
  include InfoMailer
  include InfoForm
 
  content do
    panel '選択したユーザー' do
      render 'users' # 3のviewをrender
    end

    panel 'メール作成  from:hoge@mail.com' do
      render 'form' # 4のviewをrender
    end
  end

  controller do
    def index
      # redirect
      if params[:user_ids].blank? || params[:user_ids].empty?
        redirect_to admin_users_path, notice: 'ユーザーを選択して下さい'
      else
        @info_form = InfoForm.new(user_ids: params[:user_ids])
      end
    end

    def create
      @info_form = InfoForm.new(info_form_params)
      if @info_form.valid?
        @info_form.deliver_all
        redirect_to :back, notice: 'メール送信成功'
      else
        redirect_to :back, notice: 'メール送信失敗'
      end
    end

    def info_form_params
      params.require(:info_form).permit(:to, :cc, :bcc, :subject, :body, user_ids: [])
    end
  end
end

```

##3.View:form
admin/mailerのメールフォーム

```app/views/admin/user/_form.html.haml
= form_for @info_form, url: admin_mailer_path, method: :post do |f|
  = notice
  - @info_form.user_ids.each do |user_id|
    = f.hidden_field :user_ids, multiple: true, value: user_id
  .mail_column
    = f.label :cc
    %br
    = f.text_field :cc, placeholder: 'test@test.com'
  .mail_column
    = f.label :bcc
    %br
    = f.text_field :bcc, placeholder: 'test@test.com'
  .mail_column
    = f.label :subject
    %br
    = f.text_field :subject, placeholder: 'タイトルを記入して下さい。'
  .mail_column
    = f.label :body
    %br
    = f.text_area :body, placeholder: '本文を記入して下さい。'
  .mail_column
    = f.submit 'Send email'
```

##4.View:users
admin/mailerの選択したuser欄

```app/views/admin/user/_user.html.haml
%table
  %tr
    %th id
    %th name
    %th email
  - @info_form.users.each do |user|
    %tr
      %td= user.id
      %td= user.name
      %td= user.email
= "合計: #{@info_form.users.count} 人"
```

#内部
##5.Mailer
ActiveSupportをextend

```app/mailers/info_mailer.rb
class InfoMailer < ActionMailer::Base
  extend ActiveSupport::Concern

  default from: hoge

  def send_customer(info_form, user)
    @info_form = info_form
    @user = user
    mail(
         to: @user.email,
         cc: @info_form.cc,
         bcc: @info_form.bcc,
         subject: @info_form.subject
         )
  end
end

```

##6.フォーム
ActiveSupportをextend

```
class InfoForm
  include ActiveModel::Model
  extend ActiveSupport::Concern

  attr_accessor :user_ids, :cc, :bcc, :subject, :body

  validates :subject, presence: true, length: { maximum: 10_000 }
  validates :body, presence: true, length: { maximum: 10_000 }

  def users
    @users ||= User.where(id: user_ids)
  end

  def deliver_all
    users.each do |user|
      InfoMailer.send_customer(self, user).deliver
    end
  end
end

```