MailViewの言語切り替え対応

# MailViewとは

Railsのメールを送らずに全て一覧で見れる[MailView](https://github.com/basecamp/mail_view)がすごい便利。

以下を`Gemfile`に追加。

```rb:Gemfile
gem 'mail_view', require: false
```

`bundle install`して`config/routes.rb`にマウント。

```rb:config/routes.rb
MyApp::Application.routes.draw do
  if Rails.env.development?
    mount UserMailerPreview => 'user_mailer_preview'
  end
end
```

通常の設定はこんな感じ。

```rb:lib/user_mailer_preview.rb
require 'mail_view'
class UserMailerPreview < MailView
  # わかりやすい用にメールのアクション名と同じ名前でexport
  def mail_action
    UserMailer.mail_action
  end
end
```

こんな風にindexが出る。

![Screen Shot 2014-07-09 at 7.40.53 PM.png](https://qiita-image-store.s3.amazonaws.com/0/22653/1bb85cc6-a408-870e-e760-111d0fc6594d.png)

リンクをクリックすると、メール内容がこんな感じで出る。

![Screen Shot 2014-07-09 at 7.41.19 PM.png](https://qiita-image-store.s3.amazonaws.com/0/22653/977e2a20-24ff-1875-4422-e0afc0581da0.png)

# 言語切り替え対応

MailViewは現状paramsやcookieを提供してくれないのでハックしてみた。
MailViewクラスは`call`以外のpublicメソッドは全部ルートとして認識されてしまうので注意。

```rb:lib/user_mailer_preview.rb
require 'mail_view'
class UserMailerPreview < MailView
  # わかりやすい用にメールのアクション名と同じ名前でexport
  def mail_action
    UserMailer.mail_action
  end

  def call(env)
    @request = Rack::Request.new(env)

    # パラメータかクッキーからlangを探す
    @lang = @request.params['lang'] || @request.cookies['lang']
    if new_lang = @lang
      # ActiveRecord::Baseのカラムメソッドがロードされてない時用
      u = User.new
      u.lang
      User.class_eval do
        # langメソッドをバックアップ
        alias _lang lang
        # new_langを返すように上書き
        define_method :lang do
          new_lang
        end 
      end 
    end 

    status, header, body = super(env)

    if @lang
      # langメソッドを元に戻す
      User.class_eval do
        alias lang _lang
      end
      # Cookieにlangをセット
      ::Rack::Utils.set_cookie_header!(header, 'lang', @lang)
    end 

    [status, header, body]
  end 

  protected

  # MailViewのindexページのパスを上書き
  def index_template_path
    File.join(__DIR__, 'user_mailer_preview/index.html.erb')
  end 
end
```

`mail_view`のデフォルトのindexをコピペしてきて以下のようにlangの選択をできるようにする。
凝るところじゃないので、frame組みで失礼します。

```rb:lib/user_mailer_preview/index.html.erb
<style>
  table {
    height: 100%;
    width: 100%;
    font-family: "Lucida Grande", sans-serif;
    font-size: 12px;
  }
  body {
    padding: 0;
    margin: 0;
    font-family: "Lucida Grande", sans-serif;
    font-size: 12px;
  }
  td {
    vertical-align: top;
  }
  .mail-index {
    width: 400px;
    padding: 10px 0;
  }
  .mail-index table {
    height: 0px;
  }
  .mail-index table td {
    border-bottom: solid 1px #CCC;
    padding: 2px;
  }
  iframe {
    width: 100%;
    height: 100%;
  }
</style>

<table>
  <tbody>
    <tr>
      <td class="mail-index">
        <table cellspacing="0" cellpadding="0">
          <tbody>
            <% links.each do |name, link| %>
              <tr>
                <td><a href="<%= link %>" target="FRM"><%= name %></a></td>
                <td><a href="<%= link + '?lang=en' %>" target="FRM">En</a></td>
                <td><a href="<%= link + '?lang=ja' %>" target="FRM">Ja</a></td>
              </tr>
            <% end %>
          </tbody>
        </table>
      </td>
      <td>
        <iframe src=""
          width="300" height="250" name="FRM"
          scrolling="auto" frameborder="1">
        </iframe>
      </td>
    </tr>
  </tbody>
</table>
```

こんな感じでフレームで切り替えられるようになった。
言語の切り替えもスム〜ス。

![Screen Shot 2014-07-09 at 7.33.15 PM.png](https://qiita-image-store.s3.amazonaws.com/0/22653/c00ae814-dbbd-086e-b049-22ef28ac16c6.png)