RSpecと名前付きルートの相性?
とあるアプリケーションでrake spec:viewsしたところ、以下のようなエラーになった(rspec-1.3.1、rspec-rails-1.3.3、rails-2.3.x)。
new_article_comment_url failed to generate from {:action=>"new", :controller=>"comments"} - you may have ambiguous routes, or you may need to supply additional parameters for this route. content_url has the following required parameters: ["articles", :article_id, "comments", "new"] - are they all satisfied?
問題の部分のコードは以下の通り。
On line #14 of app/views/comments/index.html.erb 11: ... 12: ... 13: ... 14: <%= link_to _('Create new comment'), new_article_comment_path %> 15: ... 16: ... 17: ...
このときのexampleは以下のようなものだった。
describe '/comments/index' do before do article = articles(:one) assigns[:article] = article assigns[:comments] = article.comments render 'comments/index' end it '...' do ... end end
実際にブラウザでアクセスした場合には問題なく動作する部分。たまたま動いているだけという可能性もあるが…… どうも何かがおかしい、気がする。
とっかかりがなかったので、他のアプリケーションでのexampleの書き方と比較したり、このエラーメッセージを出している部分からコードを遡ったり、実際にアクセスしたときのログを確認したり、改めてrake routesしたり、p @controllerしたりした。そうしたあれやこれやをやってみた結果、exampleを次のように変えればよいことがわかった。
before do article = articles(:one) request.path_parameters[:article_id] = article.to_param assigns[:article] = article assigns[:comments] = article.comments render 'comments/index' end
振り返ってみると「["articles", :articleid, "comments", "new"]」がすべて与えられていなければならない、と言われていたわけで、この中で可変なのは:articleidであった。
なお、このrequest.pathparametersはrenderのオプション引数:pathparametersとして与えることも可能なようだ。