前回まで説明で、Ruby on Railsを使った勤務情報管理アプリケーションはかなりできあがってきました。それでも、まだまだ実装すべき機能はあります。実用性を高めるために、メール通知機能を実装してみましょう。

勤務状況を更新したらリーダーにメールで通知する

 常にブラウザから勤務状況を確認できれば良いですが、忙しいリーダーともなればいつもブラウザを開いて見ているわけにはいきません。そこで自部門の勤務状況が更新されたら、上司あるいはリーダーにメールを送信して状況が更新されたことを知らせるようにしてみましょう。

リスト1●configフォルダ内のapplication.rbに追加する内容
リスト1●configフォルダ内のapplication.rbに追加する内容
[画像のクリックで拡大表示]

メール送信のための設定
 Railsでメールを送信するには、設定ファイルのconfig/application.rbに対して、リスト1のようなコードを追加しておきます。ただし、実際のサンプルを試す場合には、青字の部分は自分の環境に合わせて書き換えてください。

メール送信のためのメーラーを定義
 続いてメールを送信するためのメーラー(Mailer)を作成します。メーラーはこれまで使ってきたコントローラによく似たクラスで、要求を受けて必要な処理を行い、その結果をテンプレートを使ってメール本文に整形します。

 メーラーを作成するには、もうおなじみのrails generateコマンドを利用します。以下は、UpdateMailerメーラーにsendmail_changeという名前のメソッドを作成する例です。メソッドの名前は自由に付けて構いません。
> rails generate mailer UpdateMailer sendmail_change

リスト2●/app/mailerフォルダ内のupdate_mailer.rbに追加・編集する内容
リスト2●/app/mailerフォルダ内のupdate_mailer.rbに追加・編集する内容
[画像のクリックで拡大表示]

 作成されたメーラーは、/app/mailerフォルダ内にupdate_mailer.rbとしてできていますので、リスト2のように編集してみましょう。(1)のdefaultメソッドは、メーラーで利用する共通のヘッダー情報を「ヘッダー名 => 値,...」の形式で指定します。ここでは、最低限、差出人を表すfromヘッダーを指定しています。

 メールを作成するための処理を記述しているのは、(2)のsendmail_changeメソッドです。コントローラでいうところのアクションに相当します。引数として更新された従業員情報(employee)を受け取り、その更新情報に基づいてメールを整形しています。

 (3)で引数employeeを@employeeにセットし直しているのは、後からテンプレートで従業員情報にアクセスする必要があるためです。Employee.whereメソッドは、与えられた条件(ここでは従業員と同じ部門コードで、リーダーである人間)でemployeesテーブルを検索します。基本的に一部門にリーダーは一人であることを想定していますので、firstメソッドで最初の一件だけを取り出しています。

 メールの生成に必要なデータが準備できたら、後はmailメソッドで対応するテンプレートを呼び出し、メールを生成するだけです。defaultメソッドと同じく、引数にはメールヘッダーを指定します。この例では、宛先(to)をリーダーのメールアドレス*1とし、件名(subject)には固定値で「Status Update」と指定しています。

リスト3●/app/views/update_mailer内のsendmail_change.text.erbの内容
リスト3●/app/views/update_mailer内のsendmail_change.text.erbの内容
[画像のクリックで拡大表示]

メールテンプレートの準備
 そして、mailメソッドで呼び出されるテンプレートは、リスト3の通りです。コントローラ/ビューの関係と同じく、テンプレートのファイル名は「/app/views/メーラー名/メソッド名.text.erb」となります。違うのは、テキストメールなので拡張子が.html.erbではなく、.text.erbであるという点だけです。必要なデータを<%=... %>で埋め込めるのも、これまでと同じですね。

メール送信の指示はオブザーバーで
 メーラーの準備ができたら、今度は、これをどこからか呼び出す必要があります。今回は、勤務状況を更新したところでメールを送信したいので、Employeesコントローラのupdateアクションから呼び出しても良いのですが、更新を行う処理がほかでも発生した場合、同じような呼び出しのコードを書くのは嬉しくありません。

 そこでオブザーバという仕組みを利用します。オブザーバとはモデル(テーブル)に対する操作を監視(observe)して、保存や削除が行われたタイミングで処理を行うためのクラスです。さっそく作成してみましょう。

リスト4●/app/modelsフォルダ内のemployee_observer.rbに追加する内容
リスト4●/app/modelsフォルダ内のemployee_observer.rbに追加する内容
[画像のクリックで拡大表示]
リスト5●application.rbでオブザーバを有効にする
リスト5●application.rbでオブザーバを有効にする
[画像のクリックで拡大表示]
図1●リーダーに送信された更新情報
図1●リーダーに送信された更新情報
[画像のクリックで拡大表示]

 オブザーバそのものは、rails generateコマンドで作成できます。
> rails generate observer Employee

 これでEmployeeモデルを監視するためのEmployeeObserverクラスが/app/modelsフォルダ内にできましたので、リスト4のようにコードを追記してみましょう。after_saveメソッドは、Employeeモデルでデータが保存されたタイミングで呼び出されます。引数epは、保存されたEmployeeオブジェクトを表します。

 after_saveメソッドの中では、「UpdateMailer.sendmail_change(ep)」で更新メールを生成しています。メーラーのメソッドは、あたかもクラスメソッドであるかのように呼び出せる点に注目です。また、sendmail_changeメソッドそのものはあくまでメールを生成しているだけなので、実際に配信するにはdeliverメソッドを呼び出す必要があります。

 オブザーバの準備ができたら、最後にアプリケーション設定ファイルでオブザーバを有効にします(リスト5)。ただ、クラスを用意しただけではオブザーバは働きませんので、要注意です。設定ファイルを編集した後は、サーバーの再起動も忘れないようにしてください。

 それでは、この状態でサンプルを実行してみましょう。編集画面から勤務情報を更新し、図1のようなメールがリーダーのアドレス宛に送信されることを確認してください。