29 Jan / 2010

Variables you shouldn’t use in a rails controller

I ran into this issue and spent an hour debugging this.  Writing
it here, so it might help some one else.

Lets create a simple RAILS project

rails hello
cd hello
./script/generate controller hello

Add a simple index method

app/controller/hello_controller.rb

class HelloController < ApplicationController
  def index
  end
end

app/views/hello/index.html.erb

<html>
  <title>
  </title>
  <body>
    <h1>Hello world</h1>
    <%= link_to 'index', :controller => 'hello', :action => 'index' %>
  </body>
</html>

In your browser go to url http://localhost:3000/hello
.  You wil get the simple greeting

img

All is fine.
Now lets add an instance variable in the controller

app/controller/hello_controller.rb

class HelloController < ApplicationController
  def index
    @url = "http://www.sujee.net"
  end
end

Do a reload….

Awww….

undefined method `rewrite’ for “http://sujee.net”:String

error

So our innocent little variable caused this!!

What is going on here?  Turned out we inadvertantly over-wrote an
internal variable Rails uses; that happens to be @url.

If we change this variable to say ‘@myurl’ things start to work again.

How can we find out what variables are being used?  Lets update
our controller

app/controller/hello_controller.rb

class HelloController < ApplicationController
  def index
    puts self.instance_variables
  end
end

Reload the page.  And look at the console where ‘script/server’ is
running.

=> Booting WEBrick
=> Rails 2.3.4 application starting on http://0.0.0.0:3000
=> Call with -d to detach
=> Ctrl-C to shutdown server
[2010-01-28 23:58:10] INFO  WEBrick 1.3.1
[2010-01-28 23:58:10] INFO  ruby 1.8.7 (2008-08-11) [universal-darwin10.0]
[2010-01-28 23:58:10] INFO  WEBrick::HTTPServer#start: pid=94840 port=3000
@_session
@_params
@url
@performed_redirect
@request_origin
@_request
@_headers
@performed_render
@action_name
@template
@_response
@before_filter_chain_aborted


Processing HelloController#index (for 127.0.0.1 at 2010-01-28 23:58:14) [GET]
Rendering hello/index
Completed in 79ms (View: 77, DB: 0) | 200 OK [http://localhost/hello]

We over-wrote @url and caused the problem.
There you go, don’t name your variables as one of these:

  • @_session
  • @_params
  • @url
  • @performed_redirect
  • @request_origin
  • @_request
  • @_headers
  • @performed_render
  • @action_name
  • @template
  • @_response
  • @before_filter_chain_aborted

Thanks a bunch to my collegue Go Kojima for helping me
debug this issue.

Sujee Maniyam
Sujee is a founder, principal at Elephant Scale where he provides consulting and training on Big Data technologies

2 Comments:


  • By Walter Sheridan 10 Dec 2012

    What ist for instance the difference between @_params and params?

    When you try to merge a hash with params, it says params is nil. I just don’t get the difference…

  • By Pristi 02 Aug 2015

    I would recommend one thin prsecos per prsecosor/core. Because there is only one underlying thread, you can only peg one core at a time. Basically think of thin as Mongrel, except it can handle many concurrent requests safely.Fibers are only in 1.9. There has been some work done to port them to 1.8 but I strongly urge just upgrading. You also gain a nice improvement in Ruby execution speed.

Leave a Reply



Copyright 2015 Sujee Maniyam (