Head First Rails 8章 『アクション「news」を作成する』 のルートについて

O’Reilly の Head First Rails の8章 『アクション「news」を作成する』 (p345) で記述されているルートを設定して news.xml を表示させると、ActiveRecord::RecordNotFound in IncidentsController#show という風に show メソッドを実行しようとしてエラーとなってしまう。

調べてみると、このようなフォーラム "Error with chapter 8 files – O’Reilly Forums" があった。
config/routes.rb の最初の方にある map.resources :incidents を追加したルートの後に記述するといいらしい。

ActionController::Routing::Routes.draw do |map|
  # この設定を、追加するルートの後に記述するよう修正する
  # map.resources :incidents

  #...省略...#

  # 追加するルート
  map.connect '/incidents/news', :action=>'news', :controller=>'incidents', :format=>'xml'
  # ここに記述する
  map.resources :incidents
  map.connect ':controller/:action/:id'
  map.connect ':controller/:action/:id.:format'
end

ところが、この設定にしても show メソッドを実行しようとしてしまう。

さらに調べてみると、このような記事が、"www.gnnk.net – [Rails][本]Head First Rails"。

そこで、ルート設定のパスに .xml の拡張子を含む形で記述してみる。

ActionController::Routing::Routes.draw do |map|
  # この設定を、追加するルートの後に記述するよう修正する
  # map.resources :incidents

  #...省略...#

  # 追加するルート(news.xmlとする)
  map.connect '/incidents/news.xml', :action=>'news', :controller=>'incidents', :format=>'xml'
  # ここに記述する
  map.resources :incidents
  map.connect ':controller/:action/:id'
  map.connect ':controller/:action/:id.:format'
end

すると、この2つの修正で news.xml が表示されるようになった。

使用している ruby, rails, gem のバージョンは以下のとおり。

$ ruby -v
ruby 1.8.7 (2009-06-12 patchlevel 174) [i686-darwin10]
$ rails -v
Rails 2.3.5
$ gem -v
1.3.4

それにしても、フォーラムでもコメントされてるけど、どうして flight の場合は問題なく動作して incident の場合はダメなんだろう…

追記:p353 の auto_discovery_link_tag ヘルパーによる RSS フィードの追加にも修正が必要だった。本文のコードではフィードの URI に .xml の拡張子が付かないので、以下のように :format を指定するコードを追加した。

<%= auto_discovery_link_tag(:rss, {:action=>'news', :format=>'xml'}) %>
Head First Rails ―頭とからだで覚えるRailsの基本
David Griffiths
オライリージャパン
売り上げランキング: 45786
このエントリをはてなブックマークに追加このエントリをdel.icio.usに追加このエントリをLivedoor Clipに追加このエントリをYahoo!ブックマークに追加このエントリをFC2ブックマークに追加このエントリをNifty Clipに追加このエントリをPOOKMARK. Airlinesに追加このエントリをBuzzurl(バザール)に追加このエントリをChoixに追加このエントリをnewsingに追加
コメント

こちらの記事のおかげで、
私も動かすことができました。
ありがとうございました。
私の修正はmap.resources:incidentsの場所を
移動するのみですみました。

>どうして flight の場合は問題なく動作して incident の場合は

この部分に関しまして、解決されたでしょうか?
同じ本のp388にその答えがあるのを
本日、発見しましてスッキリしました。

確かにmap.resources:incidentsの場所を
追記ルートの下に移動する必要があり、
なおかつ、flightの場合は必要がなかったと
いうことが分りました。

通りすがりにすみませんでした。
また、ステキな記事を読むことを
楽しみにしています(*^^*)

コメント by tanamaho | 2010/03/12 - 15:51

> tanamaho さん

コメントありがとうございます。

show メソッドが呼出されてエラーとなることから、より上位にある map.resources :incidents の生成するルート
incident GET /incidents/:id(.:format) {:controller=>”incidents”, :action=>”show”}
の方にマッチしているということまではわかっていましたが、flight の場合と incident の場合との違いについてはわからないままでした。

もう一度ルート設定をよく見てみると、
flight のルート設定の場合は、自分で追加したルート設定
/flights/:flight_id/seats {:controller=>”seats”, :action=>”flight_seats”}
が scaffold で生成する map.resources :flights のルート設定にマッチしないために、修正しなくても動作したようですね。

ルートについてきちんと理解するきっかけになりました、ありがとうございました。

コメント by iNo | 2010/03/12 - 16:53

はじめまして、監訳者です。
ご指摘ありがとうございます。
こちらで書かれているとおり、
1. /incidents/news.xml のルートを map.resources :incidents よりも上に記述しないと動かないこと
2. auto_discovery_link_tag のオプションに :format=>’xml’ が必要なこと
以上2点、確かに確認いたしました。
おかげさまで、どうやら第2刷が出版されるようなので、それ以降の版では修正されているものと思います。
ありがとうございました。

コメント by a_matsuda | 2010/06/05 - 21:50

> a_matsuda さん

コメントありがとうございます。

第2版での修正のお役に立てたようで嬉しいです。

コメント by iNo | 2010/06/08 - 20:39
コメント投稿
↑ページの先頭へ