Philip7899
Philip7899

Reputation: 4677

undefined method `[]' for nil:NilClass with rails params

I have the following code:

<% if params %>
    <% puts 'user params are' + params['user'].inspect.to_s %>
           <% if params['user']['type'] == 'Student' %>
              <div class="signup-popup-bg-failure sign-freelancer"><% puts 'opt1stud' %>
          <% else%>
              <div class="signup-popup-bg sign-freelancer"><% puts 'opt2stud'%>
          <% end %>
<% else %>
    <div class="signup-popup-bg sign-freelancer"><% puts 'opt3stud'%>
<% end %>

This returns the error:

undefined method `[]' for nil:NilClass

and the line

<% if params['user']['type'] == 'Student' %>

is highlighted.

I am trying to change what css class gets displayed depending on the params.


if

params['type']['student'] 

exists, I want the class to be:

<div class="signup-popup-bg-failure sign-freelancer">


If

params['type']['Employer'] 

exists, I want the class to be:

<div class="signup-popup-bg-failure sign-freelancer">

If there are no params, I want the class to be

 <div class="signup-popup-bg sign-freelancer">

I don't understand why this error exists. The page says there are no params, so this code should not even be executed. What's even stranger is that none of the 'puts' statements are getting executed. This does not make sense either because the if/else logic dictate that one of the puts statements must be getting executed. Does anyone know how to get this code to work?

Upvotes: 0

Views: 3807

Answers (2)

Ivan Denysov
Ivan Denysov

Reputation: 1502

fast hack I'm using for such cases is:

<% if params.try(:[], 'user').try(:[], 'type') == 'Student' %>

instead of

<% if params['user']['type'] == 'Student' %>

try() method is perfectly documented here: http://apidock.com/rails/Object/try [] is a method sent to params hash. By default hash returns nil if no key found. That means that your hash doesn't have 'user' key, and params return nil instead.

You can read about params hash here: http://guides.rubyonrails.org/action_controller_overview.html#hash-and-array-parameters

puts doesn't function as you would expect in Rails. You should use logger object: http://guides.rubyonrails.org/debugging_rails_applications.html#sending-messages

something like:

logger.info params.inspect

Upvotes: 3

Helios de Guerra
Helios de Guerra

Reputation: 3475

I think you will always have params of some type, at least the action and controller.

Therefore your code is always going to be run (i.e. your if params conditional is always going to be true).

In your code you could throw in a params.inspect to see what exactly the params hash contains.

Maybe something like this would work for you:

<% if params.has_key?(:user) %>
  <% if params['user']['type'] == 'Student' %>
    ... etc ...
  <% else if params['user']['type'] == 'Employer' %>
    ... etc ...
  <% else %>
    ... default ...
  <% end %>
<% end %>

Although this code could probably be cleaned up using a presenter or decorator like the draper gem or something like on this Railscast:

http://railscasts.com/episodes/287-presenters-from-scratch.

Or even a helper method would be preferable to this kind of logic in the view layer.

Upvotes: 1

Related Questions