2

Is it possible to force Ruby/Rails to throw an error when printing/using instance variables on a view that haven't been defined on controller

I'm declaring an instance variable on a Rails Controller and I'm printing its value on a View

def controller_action
    @some_data = "some value"
end

Then we know we can print its value on a view

<p>Some data has <%= @some_data %></p>

My problem is when doing mistakes on a view like this:

<p>Some data has <%= @somedata %></p>

Ruby won't complain and it's difficult to find those mistakes. This also applies for team development where some programmer can create an instance variable on a controller with one name and another programmer expects to print it on a view but accidentally uses other name.

2
  • You could use defined? to check whether the instance variable has been defined or not. E.g. defined?(@some_data) Commented Jun 27, 2015 at 19:11
  • I'm not providing an answer, but your question right here describes the benefits of TDD. If you wrote a test for your view to determine proper displays on the view (call it feature or integration) you'd find the error in your code quickly as you write it (Red, Green, Refactor). To me it's a simpler solution than any other answer provided Commented Dec 27, 2016 at 18:21

3 Answers 3

3

Ugly Way

As @BartJedrocha said, you could manually code it at the top of your view:

<% raise "Instance variable @somedata not defined" unless defined?(@somedata) %>

You could even take it a step further and make a method in a helper that could take an array as an argument and check that each instance variable in the array is defined and raise an error if not. That's pretty annoying, though, and I haven't seen anyone doing that.


Good Way via Better_Errors Gem

I think a better solution is to only pass a single instance variable from your controller to your view, which is considered a best practice. This will cut down on the opportunities for this type of error to occur.

Additionally, while I try not to recommend code libraries as solutions, this one is so universal in Rails that I think it is acceptable: the Better_Errors gem will result in an error page that clearly lists all instance variables available to your view and would make it trivial to determine whether there is a problem there (notice the lower right section in the picture below).

Better Errors Page

The live shell will allow you to use REPL to interact with the current state to further investigate issues.


Weird Way via "Verbose" Mode

Lastly, I supposed you could attempt to run Rails in verbose mode. Verbose mode can be set when using Ruby from the command line with the -w flag and will give a warning if you attempted to use an undefined instance variable check out this resource for more. However, we are using Rails and not manually invoking Ruby ourselves, so in order to pass that in, you would probably need to set the environment variable ($VERBOSE=true) in a config file.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks Rob. Ugly way is certainly "ugly" and I can still make mistakes on variable names. Better_Errors seems promising for development in general. I'll check it out. Verbose Mode is interesting. Can I set it at runtime? For example at the beginning of a View file?
@user2997817 I'm not sure if that's possible—I was under the impression that once your interpreter is set to run that way, you can't turn it on or off without re-executing your code.
1

Simple solution: Use locals instead of instance variables

def controller_action
  render locals: { some_data: "some value" }
end

And then you can use it as a local variable/method

<p>Some data has <%= some_data %></p>

If you don't pass it, or if you do not access it properly (with a typo) you will get a no variable/method defined error.

Comments

0

Rails by default will not provide any exceptions if the variable is not declared in the controller and instead it will just treat is as a 'nil'. But even if you declare the object in controller there is still possibility for the variable to become nil. So it will be difficult to find whether the variable is nil because it was not declared or it got a nil value.

We may be able to replace the nil in rails using the to_s conversion. So please try some methods like that instead of raising an error or exception.

1 Comment

Using to_s on every variable expected to have something is actually interesting. Ruby would complain on misspelled variables as expected. However it requires the whole team to adopt this technique. I wish there were another way.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.