ActiveAdminでのmailer実装
ユーザーに管理画面(ActiveAdmin)からメールを送りたい。
公式ページ
に詳細がなかったため、メモ。
前提
- バリデーションが全てフォームで行う。
- ユーザ選択されていない場合は、ユーザータブへリダイレクトする。
- 選択されたユーザーの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