l'essentiel est invisible pour les yeux

Tuesday, April 24, 2007

[Rails] SlowQueryLoggerでRSpecのSpecファイルも実行するように変更

specの場合はmodelテストのほうが良さげ

いつかやろうと放置プレイしていたところを指摘してもらったので実装しました。

SlowQueryLogger


Index: slow_query_logger.rb
===================================================================
--- slow_query_logger.rb (revision 5)
+++ slow_query_logger.rb (revision 6)
@@ -116,10 +116,11 @@

if __FILE__ == $0
# get all controlelrs name
- controller_pattern = Pathname.new(File.join(RAILS_ROOT, 'app', 'controllers', '*.rb'))
- controllers_list = FileList.new(controller_pattern.to_s)
- controllers_list.map! { |path| File.basename(path).sub('.rb', '') }
-
+ controller_pattern = Pathname.new(File.join(RAILS_ROOT, 'app', 'controllers', '*.rb'))
+ model_pattern = Pathname.new(File.join(RAILS_ROOT, 'app', 'models', '*.rb'))
+ controllers_list = FileList.new(controller_pattern.to_s).map! { |path| File.basename(path).sub('.rb', '') }
+ models_list = FileList.new(model_pattern.to_s).map! { |path| File.basename(path).sub('.rb', '') }
+
# Clear the slow query log
ActiveRecord::Base.slow_query_logger.clear

@@ -127,14 +128,19 @@
unittest_functional_test_file = File.join(RAILS_ROOT, 'test', 'functional', "#{controller}_test.rb")
rspec_controller_spec_file = File.join(RAILS_ROOT, 'spec', 'controllers', "#{controller}_spec.rb")

- # check for unit test or spec file of rspec
+ # checks for unit test or spec file of rspec
if File.exists?(unittest_functional_test_file)
require unittest_functional_test_file
elsif File.exists?(rspec_controller_spec_file)
require rspec_controller_spec_file
-# rails_spec = Pathname.new(File.join(RAILS_ROOT, 'script', 'rails_spec')).cleanpath.to_s
-# cmd = rails_spec + " " + Pathname.new(rspec_controller_spec_file).cleanpath.to_s
-# system cmd
end
+
+ # checks for file of RSpec model's spec
end
+
+ # Checks for file of RSpec model's spec
+ models_list.each do |model|
+ rspec_model_spec_file = File.join(RAILS_ROOT, 'spec', 'models', "#{model}_spec.rb")
+ require rspec_model_spec_file if File.exists?(rspec_model_spec_file)
+ end
end



modelのSpecファイルが存在する場合には、コントローラのSpecと合わせてそちらも実行するように変更しました。RSpecでBDDを行うと、主たるロジックは全てモデルに実装してコントローラからはモデル中に定義したメソッドを呼び出すだけになる。

先日実装したActiveRecord::QueryCacheでキャッシュ戦略を管理する場合にも、モデル中のメソッド内で呼び出しているAR#find一つ一つに対してキャッシュ指定することになる。

これは細かい指定ができていいかもしれないが、モデルのメソッド(でいくつかの複雑で重いSQLを実行し加工した)結果自体をキャッシュしたいことがある。ARと直接関連するわけではないので、キャッシュの削除戦略が複雑になる。現在考え中。

こんなの?

class IndexController < ApplicationController::Base
def index
@me = session[:user]
@my_loves_friends = cache(:key => "index_controller_loves_friends", :expire => 10.minutes) do
@me.find_loves_users(:limit => 10)
end
end
end