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"} -Extracted source (around line #3):
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?
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)
2008.10.16 Thu 05:32
TRACKBACKS
この記事へのトラックバックURL: http://www.red-mount.com/trackback/13_d9448580119159c626ad1b093c7a13292c894002
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)
COMMENTS