A collection is defined in a view, where links for each element's successive and previous items need to be generated. (a css-only lightbox. While the index of those items is accessible,
<% @gallery.each_with_index do |article_gallery, index| %>
<%= succ = @gallery[index 1] %><%= succ.inspect %>
<%= prev = @gallery[index - 1] %>
<% end %>
The inspection of the object returns the expected object
#<ArticleGallery id: 1, article_id: 16, image: "Screen_Shot_2022-11-17_at_07.46.05.png", position: 2, [...]>
But it's id cannot be accessed. if succ.id
in lieu of succ.inspect
is called it is deemed to now be a nil object.
undefined method `id' for nil:NilClass
@output_buffer.safe_append=' '.freeze;@output_buffer.append=( succ = @gallery[index 1] );@output_buffer.append=( succ.id );@output_buffer.safe_append='
What is the proper way to access an attribute for the relative previous or successive object?
CodePudding user response:
On the last iteration @gallery[index 1] will return nil Try to use https://apidock.com/ruby/Enumerable/each_cons instead of each_with_index
It will be smth like:
<% @gallery.each_cons(2) do |article_gallery| %>
<%= succ = article_gallery[1] %>
<%= prev = article_gallery[0] %>
<% end %>
CodePudding user response:
The answer by Voltan is a partial answer, where it creates a useful array, but as the docs state, the return is nil
& that is failing the requirement.
But that was a bit of a lead-in ot the actual solution. The solution was around, but buried a bit deep using ruby's zip
method on array.
Given that the impact is on the view, we show the prev
and succ
id OR (to make the loop continuous) return the last or first element of the array in case the calculated index returns nil
<% @gallery.zip((0 .. (@gallery.size - 1)).to_a).each do |a, i| %>
<%= a.image_url %>
<% prev = @gallery[i-1] %>
<% if prev.nil? %>
<%= @gallery[-1].id %>
<% else %>
<%= prev.id %>
<% end %>
<% succ = @gallery[i 1] %>
<% if succ.nil? %>
<%= @gallery[0].id %>
<% else %>
<%= succ.id %>
<% end %>
<% end %>