<< back to list

Railsでモデル名に複数形を使ってはいけない あとで読む

モデル名に複数形を使うと「nil.to_sym」というNoMethodErrorが表示される

Rails(2.1.1現在)でscript/generateする時、モデル名に複数形を使ってしまうと、
config/routes.rb で map.resources を使ったRESTfulアプリケーションを作る際にエラーになります。
例えば、

ruby script/generate scaffold abouts title:string content:text

と、複数形の名称を使用してscaffoldした後に、scaffoldで生成されたコントローラーで新規作成や修正を行おうとすると

NoMethodError: You have a nil object when you didn't expect it!
The error occurred while evaluating nil.to_sym

といったエラーが表示されてしまいます。
script/generateの際に複数形ではなく単数形を使うことで、これを回避することができます。

ruby script/generate scaffold about title:string content:text

これに気付かず、数時間悩みました……。
(逆にRESTfulな場合のコントローラー名は、単数形を使ってしまうと問題が出るようです)

じゃあ、例えば「news」のように単数形も複数形も「〜s」で終わるようなイレギュラーな単語はどうするのかという事で、調べてみました。

Rails2.1.1のscaffoldは、イレギュラーな複数形を取る単語に弱い

例えば「news」は、単数形も複数形も「news」なので、まずは以下のようにしてscaffoldを実行します。

ruby script/generate scaffold news title:string content:text

script/serverで「http://localhost:3000/news」にアクセスし、ページ内の[New news]をクリックしてみると、以下のエラーが。

news_url failed to generate from {:controller=>"news", :action=>"show"} - 
you may have ambiguous routes, or you may need to supply additional parameters for this route.
content_url has the following required parameters: ["news", :id] - are they all satisfied?
Extracted source (around line #3):
3: <% form_for(@news) do |f| %>

なぜか、リンク先のURLが「{:controller=>"news", :action=>"create"}」ではなく、「{:controller=>"news", :action=>"show"}」になっています。
試しに rake routesしてみると、以下のように表示されます。(formatted_...は、省略)

news_index GET    /news                            {:action=>"index", :controller=>"news"}
POST /news {:action=>"create", :controller=>"news"}
new_news GET /news/new {:action=>"new", :controller=>"news"}
edit_news GET /news/:id/edit {:action=>"edit", :controller=>"news"}
news GET /news/:id {:action=>"show", :controller=>"news"}
PUT /news/:id {:action=>"update", :controller=>"news"}
DELETE /news/:id {:action=>"destroy", :controller=>"news"}

ちなみに、先ほど作成した「about」の方は、以下のような感じ。

    abouts GET    /abouts                          {:action=>"index", :controller=>"abouts"}
POST /abouts {:action=>"create", :controller=>"abouts"}
new_about GET /abouts/new {:action=>"new", :controller=>"abouts"}
edit_about GET /abouts/:id/edit {:action=>"edit", :controller=>"abouts"}
about GET /abouts/:id {:action=>"show", :controller=>"abouts"}
PUT /abouts/:id {:action=>"update", :controller=>"abouts"}
DELETE /abouts/:id {:action=>"destroy", :controller=>"abouts"}

「about」の方では、「abouts_path: /abouts」だったのが、「news」の方では、「news_path: /news/:id」になってしまっています。

つまり、「views/news/new.html.erb」の中では、「news_path」のリンク先が「/news」ではなく、「/news/:id」になってしまう問題が発生しているわけです。

というわけで、イレギュラーな複数形を取っている場合は、以下の対応が必要という事がわかりました。
(行数はあくまで目安です。特にshow.html.erbは、カラムの数で大きく移動します)

# app/controller/news_controller.rb:81
format.html { redirect_to(news_url) }
-> format.html { redirect_to(news_index_url) }

# app/views/news/new.html.erb:3
<% form_for(@news) do |f| %>
-> <% form_for(@news, :url=>news_index_path) do |f| %>

# app/views/news/new.html.erb:19
# app/views/news/edit.html.erb:20
# app/views/news/show.html.erb:13

<%= link_to 'Back', news_index_path %>
-> <%= link_to 'Back', news_index_path %>

つまり、「news」のように単数形も複数形も「〜s」で終わるようなイレギュラーな単語は、今のところ手作業で差分を修正するしかないようです……。

とはいえ、この辺はscaffoldのテンプレート*1を修正することでどうにかなりそうな気もするので、修正プラグインを誰か作ってくれないかなー、なんて思っている今日この頃。

*1 ちなみに、うちのMacだと、scaffoldのテンプレートは「/Library/Ruby/Gems/1.8/gems/rails-2.1.1/lib/rails_generator/generators/components/scaffold/templates」にありました。

Ruby, Rails, scaffold | comments(0) | trackbacks(0)   このエントリーを含むはてなブックマーク Yahoo!ブックマークに登録 livedoor クリップに登録 del.icio.usに登録 Google Bookmarks に追加 この記事をBuzzurlに追加 2008.10.16 Thu 05:32

COMMENTS

name : email : url :  
captcha: simple_captcha.jpg(全て大文字のアルファベットです)
画像中の文字とおなじものを入力してください。
comment:
コメントには日本語を必ず入力してください。(スパム対策です)
COMMENT

TRACKBACKS

この記事へのトラックバックURL: http://www.red-mount.com/trackback/13_d9448580119159c626ad1b093c7a13292c894002

<< back to list
 

ABOUT ME

tak (Takahito Sezutsu)

コメント、トラックバックはお気軽に!

COMMENTS

  • Beanstalk - WEBで管理可能なフリーのSubversionサーバー
    LILAC (08.14)
  • CSS Nite in Ginza Vol.29に行ってきました。
    Betsy (05.14)
  • 「オリジナルの項目が見つからなかったので、エイリアス“********”は開けません。」と出て、Finderで外付けHDDが開けない時は
    poo (04.19)
  • MacのSkypeでログイン時プルダウンメニューに表示されるSkype名を消す方法
    tak (06.22)
  • 「オリジナルの項目が見つからなかったので、エイリアス“********”は開けません。」と出て、Finderで外付けHDDが開けない時は
    tak (06.22)
  • 「オリジナルの項目が見つからなかったので、エイリアス“********”は開けません。」と出て、Finderで外付けHDDが開けない時は
    ko (06.22)
  • MacのSkypeでログイン時プルダウンメニューに表示されるSkype名を消す方法
    Mac (05.06)
  • MacのSkypeでログイン時プルダウンメニューに表示されるSkype名を消す方法
    tak (03.11)
  • MacのSkypeでログイン時プルダウンメニューに表示されるSkype名を消す方法
    tama (03.11)
  • Mac版ATOK定額制(体験版)を1週間使ってみた
    tak (09.19)
フィードメーター - RED-MOUNT.COM
あわせて読みたいブログパーツ