optional local variables in rails partial templates: how do I get out of the (defined? foo) mess?

Viewed 88396

I've been a bad kid and used the following syntax in my partial templates to set default values for local variables if a value wasn't explicitly defined in the :locals hash when rendering the partial --

<% foo = default_value unless (defined? foo) %>

This seemed to work fine until recently, when (for no reason I could discern) non-passed variables started behaving as if they had been defined to nil (rather than undefined).

As has been pointed by various helpful people on SO, http://api.rubyonrails.org/classes/ActionView/Base.html says not to use

defined? foo

and instead to use

local_assigns.has_key? :foo

I'm trying to amend my ways, but that means changing a lot of templates.

Can/should I just charge ahead and make this change in all the templates? Is there any trickiness I need to watch for? How diligently do I need to test each one?

12 Answers

I do this:

<% some_local = default_value if local_assigns[:some_local].nil? %>

How about

<% foo ||= default_value %>

This says "use foo if it is not nil or true. Otherwise assign default_value to foo"

I think a better option that allows for multiple default variables:

<% options = local_assigns.reverse_merge(:include_css => true, :include_js => true) %>
<%= include_stylesheets :national_header_css if options[:include_css] %>
<%= include_javascripts :national_header_js if options[:include_js] %>

Ruby 2.5

Erb

It's possible, but you must to declare your default values in the scope.

VARIABLE the word for replacement.

# index.html.erb
...
<%= render 'some_content', VARIABLE: false %>
...

# _some_content.html.erb
...
<% VARIABLE = true if local_assigns[:VARIABLE].nil? %>
<% if VARIABLE %>
    <h1>Do you see me?</h1>
<% end %>
...

If you do not want to pass local variable to partial each time you call it you do this:

<% local_param = defined?(local_param) ? local_param : nil %>

This way you avoid undefined variable error. This will allow you to call your partial with/without local variables.

Related