Railsのエラー
喉元過ぎれば熱さ忘れるということもあり、あとで同じようなことが起きたときに「あれ、なんだっけ?」とならないようにメモ。エラーメッセージをググって探しにくる人のためになればなおよろし。
NoMethodError (undefined method `params?' for #):
ItemsController には `params?' というようなメソッドはないということで、そのまんまの意味。
- メソッド名の綴りが間違ってる。他を疑う前にまず自分を疑うこと。
- module のメソッドの場合、module_function するのを忘れて、public になってない。
- 同じく module の場合、include していない。
- Mongrel を再起動しないでテストしてるときは、debugger で止めて、load '???.rb' で明示的にリロードしてやらないと、require もしくは include はリロードされない。(これは結構はまる)
NameError (undefined local variable or method `ken_set' for #):
ローカル変数が定義されていないか、メソッドがないと言われてる。
- 上のメソッドがない場合とほぼ同様のケース
- 「return i if (i=j)>0」のような後置if文を使うケースで、if文の中で変数を定義して、True だったらその変数を使うみたいにやってると、このエラーになる。こういう書き方はNG。ちなみに「if (i=j)>0 then return i end」はOK。
TypeError (ApplicationController is not a module):
自分定義のモジュール名に「module ApplicationController」と付けたら、案の定怒られた。
NoMethodError (You have a nil object when you didn't expect it!
このメッセージの続きは「You might have expected an instance of ActiveRecord::Base. The error occurred while evaluating nil.[]=):」となってる。
- 「nil.=」でわかる通り、nil オブジェクトに .= メソッドを適用しようとしてエラーになってる。なにをしようとしていたかというとこんなこと(↓)。
@item = Item.find_by_name(iname)
if @item.blank?
@item[:name] = iname
@item.save
end
もちろんこれで動くはずはなく、こっち(↓)が正解。.new で入れ物を作ってから .save すること。
@item = Item.find_by_name(iname)
if @item.blank?
@item[:name] = Item.new({:name => iname})
@item.save
end
ActiveRecord::StatementInvalid
続きはこちら(↓)。
(Mysql::Error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'Jun 04 17:16:30 +0900 2008) ' at line 1: SELECT * FROM `items` WHERE ( updated_at > Wed Jun 04 17:16:30 +0900 2008) ):
一見して SQL の書き方がまずい。find の :conditions にハッシュを使えばこういうことにならないんだけど、自分で WHERE句を文字列として組み立てようとするとこういうはめになる。
Item.find(:conditions => ["updated_at > ?", 1.days.ago] # ← 正しい
Item.find(:conditions => "updated_at > #{1.days.ago}" # ← 間違い
Item.find(:conditions => "updated_at > #{1.days.ago.to_s(:db)}" # ← 正しい
to_s(:db)とやると「updated_at > '2008-06-04 17:25:13'」というような文字列を返してくれる。
ActionView::TemplateError (undefined method `merge' for "1":String)
続きは「on line #12 of items/_form.html.erb:」など。
<%= f.check_box 'cache_on', '1' %><%= f.label 'cache_on', 'キャッシュON' %>
check_boxをチェックされた状態にしたくて適当に'1'とかしてみたらこういうエラー。本当はこう(↓)しないといけなかった。
<%= f.check_box 'cache_on', {'checked' => 'checked'} %><%= f.label 'cache_on', 'キャッシュON' %>