render :templateで意味不明なエラーにはまった

やったこと

コントローラで、動的コンテンツのURLを生成し、それをビューで表示するロジックを書いた。

def show
  @content = Content.find_by_id(params[:id])
  @url = @countent.url
  render :template => "/users/common/content"
end

そして、テストコードはこんな感じ

def test_show
  get :show, :id => @content.id
  assert_response :success
  assert_template "show"
  assert_equal @content, assigns(:content)
  assert_equal @content.url, assigns(:content).url
end

そして、テストコードを走らせたら、次のようなエラーがでた。

  • エラー内容

test_show(ContentControllerTest):
NoMethodError: You have a nil object when you didn't expect it!
The error occurred while evaluating nil.gsub
C:/demo/trunk/config/../vendor/plugins/jpmobile/lib/jpmobile/emoticon.rb:57:in
`unicodecr_to_external'
C:/demo/trunk/config/../vendor/plugins/jpmobile/lib/jpmobile/filter.rb:167:in
`
to_external'
C:/demo/trunk/config/../vendor/plugins/jpmobile/lib/jpmobile/filter.rb:46:in
`a
fter'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/action_controller/filters.rb:602:
in `proxy_before_and_after_filter'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/action_controller/filters.rb:470:
in `call'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/action_controller/filters.rb:470:
in `call'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/action_controller/filters.rb:637:
in `call_filter'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/action_controller/filters.rb:638:
in `call_filter'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/action_controller/filters.rb:438:
in `call'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/action_controller/filters.rb:637:
in `call_filter'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/action_controller/filters.rb:638:
in `call_filter'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/action_controller/filters.rb:438:
in `call'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/action_controller/filters.rb:637:
in `call_filter'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/action_controller/filters.rb:638:
in `call_filter'

・・・

c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/action_controller/test_process.rb

353
in `get'

content_controller_test.rb:168:in `test_show'

※このアプリケーションでは、Jpmobileプラグインを使っている。


意味不明。でも、次の様にするとエラーがなくなった。

def show
  @content = Content.find_by_id(params[:id])
  @url = @countent.url
  render :template => "/users/common/content", :layout => false
end

レイアウトファイルに変なところがあるわけではないが、何故だろう。
もう少し悩んだら、原因が分かった。

原因

以下と同じ。

そんでまあ、結局何が悪かったのかと言うと、何のこたぁない。 @template っていうインスタンス変数は ActionController::Base 内で思いっきり予約語的に使われてるので、これを書き換えてしまった結果、いざレンダリングしようとしたときにそこら辺の処理がグダグダになってるのである。

今回の場合は、@urlがActionController::Baseで使われており、それを上書きしてしまったからだ。次の様にしたら上手く行った。

def show
  @content = Content.find_by_id(params[:id])
  @content_url = @countent.url
  render :template => "/users/common/content"
end