Cameron Schultz
Cameron Schultz

Reputation: 11

Rails undefined method `name' for nil:NilClass

When iterating through my Items array, I am trying to print the item, along with the previous item in the array, but I am having some difficulty doing so. Each image I want to print is the same as the item name. The code where I get my error is as follows:

<% @items.each do |item| %>
<img src="/assets/<%= item.name %>.jpeg" >
//This is where I get my error//
<img src="/assets/<%= @items[item.id - 1].name %>.jpeg" >
<% end %>

It prints out the error: undefined method `name' for nil:NilClass. However if I change the line where the error occurs to "<%= @items[item.id].class %>" it shows that the class is an Item rather than nil. Also if I hard code the number in, such as ".jpeg" >" rails correctly outputs the picture.

Upvotes: 1

Views: 828

Answers (2)

Peter Sobot
Peter Sobot

Reputation: 2557

You're already iterating over the @items array, with each item in the variable item. However, there's no guarantee that the .id attribute on each item will correspond to its exact position in the @items array. If each item in your database has a different .id, then there's no guarantee that there are even that many items in your @items array.

For example, in this array:

@items = {{id: 5}, {id: 10}}

each item has the index 0 and 1 in the @items array. However, trying to find the "previous" item by doing @items[item.id - 1] will result in Ruby looking for an item at index 4 in the @items array - which doesn't exist.


each_with_index will help you solve this problem though - you can use it to get the actual index of each item in the array, instead of depending on the .id attribute. Something like this:

<% @items.each_with_index do |item, index| %>
    <img src="/assets/<%= item.name %>.jpeg" >
    <img src="/assets/<%= @items[index - 1].name %>.jpeg" >
<% end %>

Upvotes: 2

Francisco Soto
Francisco Soto

Reputation: 10392

From what I can see:

@item is NOT defined, you probably meant @items, and in that case, what you did won't help you either most probably because the the id on your current item has nothing to do with the index in the collection.

If instead of copy/pasting you typed that and you indeed have @items there, you still have the problem that item.id - 1 is not what you mean. You probably mean:

<% @items.each_with_index do |item, i| %>
<% i = i - 1 %>
<img src="/assets/<%= item.name %>.jpeg" >
//This is where I get my error//
<% unless i < 0 %>
<img src="/assets/<%= @items[i].name %>.jpeg" >
<% end %>
<% end %>

AND if you still are getting that, then it means you have nils in your collection and you need:

<% @items.compact.each_with_index do |item, i| %>
<% i = i - 1 %>
<img src="/assets/<%= item.name %>.jpeg" >
//This is where I get my error//
<% unless i < 0 %>
<img src="/assets/<%= @items[i].name %>.jpeg" >
<% end %>
<% end %>

Upvotes: 3

Related Questions