Do you still render your Rails views with ivars?

2015, Nov 23    

“Convention over configuration” is the well-known Rails slogan. It helps you to launch your project quite quickly when you stick to the famous “Rails Way”. Unfortunately, not for free. Your code will be hard to maintain, extend and even understand. Sooner or later. My mate once told me that “Sometimes it’s better to repeat something important than to say something new”, so let me now repeat you something that you’ve probably heard before: render your Rails views with locals, not instance variables. And here’s why.

Cleaner code with explicitly passed locals

That’s most important for me. I do not need to look for all the @ivars mixed in the code. One quick look at the end of the method and ‘viola!’ - I see all the things passed to the views. Maybe it’s not so bad when you compare “the Rails way” method like:

def show
  @item = Item.find(params[:id])
end

with:

def show
  item = Item.find(params[:id])

  render locals: { item: item }
end

but consider a 40 lines method (yes, it’s too long!) with dozen @ivars rendered somewhere in its code.

No head scratching while thinking about instance variables values

Have you ever thought why your @ivar is nil, or where its value is actually set? Maybe it comes from a controller action? Maybe from a helper? When I define my locals I always put this (more or less)

render locals: { var_name: value, another_var_name: another }

at the end of my method, so I almost instantly know what exactly is being passed to the view.

Easier debugging

Another good thing about rendering locals is that your views will tell you in details that you’re wrong when you try to use a local variable which is not passed in. With instance variables, it’s not so obvious what happened when you suddenly get a nil. If you’re lucky enough an exception is raised or you get an error, but you can’t count on it every time.

Locals are more like Object-Oriented

I know that a typical Rails development process is far away from following the OO patterns and changing your @ivars to locals does not save the world. However, in my opinion, pasting instance variables everywhere and “connecting” controllers with views by using @ivars smells really bad for me.

Cons…?

There’s only one disadvantage of this approach: locals are not available in your partial views “automagically”, so you need to keep tracking all the places in the code where the certain view is called. But wait… is that really a disadvantage? You’re more familiar with your code by that! ;-)

Conclusion

The problem of @ivars vs locals seems not to be a really big deal, but you should improve your code whenever it’s possible. For me, explicit view rendering with locals in Rails is a day to day basis.

Further reading:

  1. Fearless Rails Refactoring: Explicitly render views with locals by Andrzej Krzywda
  2. http://fweepcode.blogspot.com/2013/05/railss-controllers-and-views-are-too.html
  3. http://naildrivin5.com/blog/2014/02/09/a-defense-of-ivars-in-rails-controllers.html
  4. http://thepugautomatic.com/2013/05/locals/