以前 Rails, RSpec, Spork(, Guard) で適切にクラスをリロード という記事を書いたんですが、あれだとロケールファイルをリロードしてくれないという問題があって、調べてたら、もっとシンプルな書き方ができたので、紹介します。
確認したバージョンは下記のとおり。Rails のバージョンがちょっと古いとだめかも。
- rails 3.2.6
- rspec 2.11.0
- spork 0.9.2
- guard 1.2.3
config/environment/test.rb は前回と変わりません。Spork 使うときだけ cache_classes を false にします。
# config/environment/test.rb
Blog::Application.configure do
# Spork 使用時はクラスをキャッシュしない
if defined?(Spork) && Spork.using_spork?
config.cache_classes = false
else
config.cache_classes = true
end
end
spec/spec_helper.rb がだいぶ簡潔になりました。
#spec/spec_helper.rb
Spork.each_run do
if Spork.using_spork?
# app 下のファイル / locale / routes をリロード
# railties-3.2.3/lib/rails/application/finisher.rb あたりを参考に
Rails.application.reloaders.each{|reloader| reloader.execute_if_updated }
# machinist gem を利用してる場合、blueprints を再度読み直す
# load "#{File.dirname(__FILE__)}/support/blueprints.rb"
end
end
Rails.application.reloaders は ActionDispatch::Reloader の配列で、それぞれの条件に応じていろいろリロードしてくれます。development 環境ではこれによってクラスリロードを実現しています。
app 下のファイル、routes、ロケールファイルがリロードされることを確認しました。observer も問題なく動きます。
ActionDispatch::Reloader#execute_if_updated でなく execute というメソッドもありますが、execute_if_updated はファイルの更新の有無をチェックしてるようで、若干速いです (それなりの規模のプロジェクトで 200ms -> 40ms くらい)。Rails 3.2 で開発環境でのクラスリロードが速くなるよーって言ってたのはこれのことですね。