Don’t overwrite Rails’ built-in instance variables
February 13, 2009So I'm hammering away at a project tonight, writing a few specifications for a module. I've changed very little - or so I think - when five of my specifications start reporting this error:
NoMethodError in 'LoansController POST 'create' with valid parameters should succeed'
undefined method `env' for
This happens on the line where I call post :create in a controller spec. Undefined method 'env'? What's that about? I'm certainly not trying to call a method named "env".
It took me a little bit to figure out what was going on. See, this series of tests needed access to a particular LoanRequest object I was pulling out of fixtures. So I'd put above the tests:
before(:each) do
... some other stuff ...
@request = loan_requests(:johns_loan_request) # fetch fixture
end
Well, kids, it just so turns out that it's a bad idea to overwrite the @request instance variable in any rails context. Who knew?
Come to think of it, it would be nice to change the accessibility and/or mutability of Rails' basic instance variables and classes to prevent this kind of accidental overwrite by the programmer. Because when you make that mistake, it's invariably a bit of a pain to figure out because the error it causes is obscure.
Maybe I'll have to dig into the code one of these days to see if anything can be done about it.
Preventing an instance variable being changed isn’t something that Ruby can do. You can only access @variable within the context of an instance, but within the instance you can do anything you want with it.
Your options are:
Update the Rails RSpec contexts to check that the instance variables respond to the right methods so that no matter what ill-informed (for which I’d blame Rails, not a spec writer) modifications are made, a spec fails with a clear indication of the problem (“@request should reply to :env”)
Remember to use setters for Rails variables: self.request= … which I’d hope would perform those tests, or construct a proper request for them.
Add A Comment