シングルトン・リソース
2008/12/21
前回は、blog_entries コントローラの機能テストを通しました。
今日は、account コントローラです。
> ruby -Itest test/functional/account_controller_test.rb Loaded suite test/functional/account_controller_test Started FF.... Finished in 0.262014 seconds. 1) Failure: test_edit1(AccountControllerTest) [/usr/lib/ruby/gems/1.8/gems/actionpack-2.2.2/lib/action_controller/assertions/selector_assertions.rb:297:in `assert_select' test/functional/account_controller_test.rb:49:in `test_edit1' /usr/lib/ruby/gems/1.8/gems/activesupport-2.2.2/lib/active_support/testing/setup_and_teardown.rb:60:in `__send__' /usr/lib/ruby/gems/1.8/gems/activesupport-2.2.2/lib/active_support/testing/setup_and_teardown.rb:60:in `run']: Expected at least 1 element matching "form[action='/account']", found 0. <false> is not true. 2) Failure: test_routing(AccountControllerTest) [test/functional/account_controller_test.rb:18:in `test_routing' /usr/lib/ruby/gems/1.8/gems/activesupport-2.2.2/lib/active_support/testing/setup_and_teardown.rb:60:in `__send__' /usr/lib/ruby/gems/1.8/gems/activesupport-2.2.2/lib/active_support/testing/setup_and_teardown.rb:60:in `run']: The generated path <"/account/show"> did not match <"/account"> 6 tests, 17 assertions, 2 failures, 0 errors
今回は、ページネーションには関係ないようですね。
テストメソッド test_routing
から見ていきましょう。失敗は次の箇所で起きています。
assert_generates '/account', { :controller => 'account', :action => 'show' }
これは、Rails 2.0 からシングルトン・リソースのコントローラの名前が単数形から複数形に変わったことによるものです。
account
リソースに対応するコントローラは account_controller.rb
ではなく、accounts_controller.rb
になりました。そのため、ルーティングが混乱してしまったのです。
シングルトン・リソースとは
ある文脈において、Web アプリケーションにひとつしかないリソースのこと。
例えば、「アカウント」というリソースは複数存在しますが、あるユーザーがログインした状態において、「私のアカウント」というリソースはひとつしか存在しません。
Rails では、/accounts
という URL パスで「アカウントのリスト」を表し、/accounts/99
で「id が 99 のアカウント」を表し、/account
で「私のアカウント」を表します。
Rails 1.2 時代には、普通のリソースとシングルトン・リソースとでコントローラを別々に用意する必要がありましたが、Rails 2.0 以降は同じコントローラで処理できるようになりました。
以下の手順でテストが通ります。
/app/controllers/account_controller.rb
のファイル名をaccounts_controller.rb
に変更します。accounts_controller.rb
を開いて、クラス名をAccountController
からAccountsController
に変更します。/app/views/account
ディレクトリの名前をaccounts
に変更します。/test/functional/account_controller_test.rb
のファイル名をaccounts_controller_test.rb
に変更します。accounts_controller_test.rb
を開いて、次のように修正します。- 2-5行目を削除します。
- クラス名を
AccountControllerTest
からAccountsControllerTest
に変更します。 setup
メソッドの中で使われている、AccountController
をAccountsController
に変更します。test_routing
メソッドを次のように修正します。
def test_routing assert_generates '/account', { :controller => 'accounts', :action => 'show' } assert_generates '/account/edit', { :controller => 'accounts', :action => 'edit' } assert_generates '/account', { :controller => 'accounts', :action => 'update' } end
test:functionals
タスクを実行すると…
92 tests, 315 assertions, 0 failures, 4 errors
失敗の数が 2 から 0 に減りました。残りは、エラー 4 個です。本日はここまでとしましょう。