Rails2.3アプリをRails3.2にアップグレードする、その3
少し間が開きましたが、今回はメール、Cucumber、Javascriptまわりです
メール送信
ActionMailer
メールは Rails3で ActionMailerで仕様が以下のように少し変わりました。またActionMailerを継承したクラスは app/mailers に置くようになりました。
仕様の変更は機械的に変更できるものばかりですね。
- Rails 2.3
class CustomerMail < ActionMailer::Base helper :application # パスワード再設定用メールの送信 def password_reset(to_addr, url, timeout, name) subject "パスワードの再設定" recipients to_addr from FROM_ADDRESS body :url=>url, :timeout=>timeout, :name=>name end ・・・
- Rails 3.0 以降
class CustomerMail < ActionMailer::Base helper :Application # パスワード再設定用メールの送信 def password_reset(to_addr, url, timeout, name) @url = url @timeout = timeout @name = name mail( :subject => "パスワードの再設定", :to => to_addr, :from => FROM_ADDRESS) end ・・・
テンプレート (view)
メールのテンプレート (view)はほぼそのまま使えます。ただし < & > 等がエスケープされますので、raw を追加する必要がある部分もあるかもしれません。
日本語
あいかわらず、日本語メールが送れません ^^);
mail-iso-2022-jp という gem をインストールすると ISO-2022-JP のメールが送信できます。 ただし、この場合は UTF-8からJISコードに変換出来ない文字でエラーが発生するので、何らかの対応を考えておく必要があります。
最近はPCはもちろん、携帯でもUTF-8のメールを受信出来るようなので、UTF-8で送信すれば上の文字コードの問題は発生しません(一部のメーラー、携帯では文字化けするかも知れませんが・・・)。
私が Rails3.0以降に作ったシステムでは UTF-8で送信していますが、今のところ問題は無いようなので、今回もUTF-8で送信する事にしました。
Rails3で送信するメールの本文をbase64ではなく8bitにする方法 - 思っているよりもずっとずっと人生は短い。 を参考に、 Mail::Message deliver_jp メソッドを追加して使っています(もちろん deliverを置き換えても良いのですが・・・)。
module Mail class Message def deliver_jp self.tap {|m| m.transport_encoding = '8bit'}.deliver end end end
Cucumber
このアプリでは受け入れ(統合?)テストを Cucumber で書きました。 その時点ではCucumber 0.8.3 で Webrat を使っていました。 今回は Cucumber 1.1.9 + Capybara-webkit です。
設定や基本的なstep ファイル
設定や web_steps.rb 、 web_steps_ja.rb は空のRailsプロジェクトにCucumberをインストールして出来た物をベースに必要な部分のみ Rails2.3からコピーしました。
step の中で 他のステップを利用する場合は step と書くように変わったんですね
- Cucumber 0.8.3
When /^"([^\"]*)"ボタンをクリックする$/ do |button| When %Q(I press "#{button}") end
- Cucumber 1.1.9
もし /^"([^"]*)"ボタンをクリックする$/ do |button| step %{I press "#{button}"} end
シナリオ(フィーチャー)
Cucumberが正常に動くようにるにのに手間がかかりましたが、ほとんどのシナリオはそのまま通りました。
問題があったのは
- 画像をボタンのように使っている場合
<a href="action"><img src="a_button.png" title="Aボタン"/></a>
上のHTMLは もし "Aボタン"リンクをクリックする と書けたのですが、Captbaraは画像のtitleを見てくれません。ここは仕方なく もし "a_button"リンクをクリックする と変更しました。(a タグにtitleを付けたりしたのですがダメでした・・・・)
- エラーメッセージ
Rails2.3ではvalidationのエラーメッセージは 名前 を入力して下さい のように入力項目とエラーメッセージの間にスペースがあったのですがRails3.2では無くなっていましたので修正しました。
- visit のオプション引数
Webrat では visitのオプション引数でパラメターやメソッド(POST,PUT...)を指定できたので Javascript でリンクからPUTを送る部分は、これを使ってテストしていましたがCapybaraではvisitのオプション引数はありませんでした。
しかし、今回はJavascriptが動作するCapybara-webkit なので step はリンクのクリックを書くだけで正しくテストが行えました。素晴らしい!
Javascript関連
- :method => :delete のリンク
: method => :delete のリンクが正しく動作しませんでした。 じつはRails2.3の時点で jquery を使っていたので jquery.js ファイルもそのまま使っていましたが、バージョンが1.3.2 と古く、これが原因でした! Rails3.2の jquery.js を使うようにしたら動きました。
- :method => :delete のリンクをクリックすると Can't verify CSRF token authenticity が発生
ログアウトリンクをクリックすると、セッションが消えてしまう(新しくなってしまう)という不思議な現象が発生していました。ログを良くみると WARNING: Can't verify CSRF token authenticity と出ていいます。たしかに authenticity_tokenが来ていません・・・・・ ここで、Rails3のlayoutテンプレートの
の最後に <%= csrf_meta_tags %> が在ることを以前から不思議に感じていた事を思い出し、layoutテンプレートに加えたところ、正しく動作するようになりました ^^)/Rails2.3からRails3.2へのポーティングはかなり完成に近づいて来ました。