Get ActiveRecord value with outer index on Rails4 - ruby-on-rails

When I get List of Members in controller, I think #Members is array of ActiveRecord.
member_controller.rb
#members = Member.where(params[:param1])
So I know normally I write below to display.
member.html.erb
<% #members.each do |member| %>
<%= member.name %>
<% end %>
But in case of below, I would like to write index number at least loop 10 times like this.
<% (0..10).each do |idx| %>
<%= idx %>:
<%= members[idx].name %>
<% end %>
But it does not work. It can not be displayed members[idx].name
How can I make it?

Why don't you just use each_with_index method?
<% #members.each_with_index do |member, index| %>
<%= index %>
<%= member.name %>
<% end %>
If you need only 10 records, limit #members at the controller:
#members = Member.where(column: params[:column]).limit(10)
Does this help you?

Fix is
<% (0..10).each do |idx| %>
<%= idx %>:
<%= #members[idx].name %>
<% end %>
You forgot to use #. It should be #members, not members. And, if your query to the controller returns less than 10, then your looping way will crash. You will get the error,NoMethodError like NoMethodError: undefined method name' for nil:NilClass.
You can do as,
<% #members.each_index do |idx| %>
<%= idx %>:
<%= #members[idx].name %>
<% end %>

You can use each_with_index:
<% #members.each_with_index do |member, idx| %>
<%= idx %>:
<%= member.name %>
<% end %>
You could then use limit to limit the number of records returned.

Shouldn't it be
<% (0..10).each do |idx| %>
<%= idx %>:
<%= #members[idx].name %> #you forgot '#'here
<% end %>
Though each_with_index is a better option here

Thank you all. It worked!!
<% (0..10).each do |idx| %>
<%= idx %>:
<%= #members[idx].nil? ? '': #members[idx].name %>
<% end %>

Related

How to get previous item in each loop

I have a SQL query that loads information into a hash. I want to iterate through that information and output it into the view.
If the user_id is the same as the previous object's user_id, I don't want to display that user_id, just the name and everything else. It seems like the logic should be simple, but being a novice at Ruby and Rails, I'm not sure what is really available to do this.
I was trying something like this, but prev_id was never getting updated after the first iteration:
<% #session.each_with_index do |s, x| %>
<% if x == 0 then prev_id = 'nil' end %>
<% curr_id = s['id'] %>
<% if curr_id != prev_id %>
<%= s['id'] %>
<% end %>
<%= s['name'] %>
<%= s['count'] %><br>
<% prev_id = curr_id %>
<% end %>
Any help is greatly appreciated!
You have to declare your prev_id outside of the loop for it to persist between iterations:
<% prev_id = nil %>
<% #session.each_with_index do |s, x| %>
<% if x == 0 then prev_id = 'nil' end %>
<% curr_id = s['id'] %>
<% if curr_id != prev_id %>
<%= s['id'] %>
<% end %>
<%= s['name'] %>
<%= s['count'] %><br>
<% prev_id = curr_id %>
<% end %>
You should use chunk.
<% #session.chunk{|s| s["id"]}.each do |curr_id, a| %>
<%= curr_id %>
<% a.each do |s| %>
<%= s["name"] %>
<%= s["count"] %><br>
<% end %>
<% end %>

How to add a delimiter/separator to a Rails block

I have the following block:
<% #place.each do |f| %>
<%= f.name %><br>
<%= f.type %>
<% end %>
which prints horizontally using display: inline-block. How can I add a seperator or delimiter in between each pair, but not after the last one?
It should look something like this:
printout - printout - printout - printout
You can use the join method of Arrays :
<%=
#place.map { |f| "#{f.name}<br>#{f.type}" }
.join(' - ')
.html_safe
%>
A common approach, without a counter:
<% #place.each do |f| %>
<%= f.name %><br>
<%= f.type %>
<% if f != #place.last %>
<div class="delimiter">-</div>
<% end %>
<% end %>
Someone wrote an excellent answer that worked, but he took it down before I could accept it as the right one. Basically, I added an index to the block:
<% #count = #place.count %>
<% #place.each_with_index do |f, index| %>
<%= f.name %><br>
<%= f.type %>
<% if index + 1 < #count %>
<div class="delimiter">-</div>
<% end %>
<% end %>
and then styled the delimiter with display: inline;.
Thank you, whoever posted that answer.
Some remake of barbolo version, that caches last:
<% #place.each_with_object(#place.last) do |f, last| %>
<%= f.name %><br>
<%= f.type %>
<%= "-" unless f == last %>
<% end %>

How do I separate elements by their type with an each method?

I created two scaffolds: announce_sections and announcements. The announce_sections are the types of announcements there are (i.e. games, tryouts, etc) and when I create an announcement I specify what type of announce_sections it is. I'm trying to display it so that each announce_section is viewed, with each announcement and its information under the announce_section. This is what I came up with:
<% #announce_sections.each do |announce_section| %>
<%= announce_section.name %>
<% #announcements.each do |announcement| %>
<%= announcement.announcement_title %>
<%= announcement.information %>
<%= announcement.additional_information %>
<%= announcement.type %>
<% end %>
<% end %>
However, this code only displays the announce_sections with the all announcements under it. The announcements don't get separated into their respective announce_sections. How do I change it so that it does?
<% #announce_sections.each do |announce_section| %>
<%= announce_section.name %>
<% #announcements.where(type: announce_section).each do |announcement| %>
<%= announcement.announcement_title %>
<%= announcement.information %>
<%= announcement.additional_information %>
<%= announcement.type %>
<% end %>
<% end %>
Use the name of the field you are using to assign the announcement type instead of 'type'
There are many ways to solve this, but one simple one is to build a hash where the key is the type of announcement_section and the value is an array (or Set) of the announcement. One way to build that hash is to use the Hash.new {|hash, key| ... } form of the constructor.
#hash = Hash.new {|hash, section| hash[section] = Array.new }
#announcements.each do |a|
# for each announcment append it to the array under the hash
#hash[a.section] << a
end
And then, in the view
<% #hash.keys.each do |section| %>
<%= section %>
<% #hash[section].each do |announcement| %>
<%= announcement.announcement_title %>
<%= announcement.information %>
<%= announcement.additional_information %>
<%= announcement.type %>
<% end %>
<% end %>

Rails iteration for fields in view

i would like to iterate out some field names, appending the index number to the name of the field e.g. claim_1, claim_2, claim_3 etc
Simplified view:
<% (1..4).each_with_index do |index| %>
<%= f.label :claims_index %>
<% end %>
How can I get the index to be either 1, 2, 3, 4 or whatever respectively?
Actually you don't need each_with_index iterator for this -
<% 1.upto(4) do |i| %>
<%= f.label "claims_#{i}" %>
<% end %>
<% (1..4).each_with_index do |index| %>
<%= f.label "claim_#{index}" %>
<% end %>
Not sure whether this is what you're after but each_with_index takes two arguments so you could do:
<% #claims.each_with_index do |claim,index| %>
<%= "#{index+1}: #{claim.name}" %>
<% end %>
Which will print out each claim name and the index (1,2,3,4) The +1 makes it 1 based, rather than 0 based.
Alteranatively, simply use:
<% (1..4).each do |i| %>
<%= i %>
<% end %>

Using to_sentence

I'm a newbie...
I know how to use "to_sentence" when I have something like:
<%= #blah.collect {|b| b.name}.to_sentence %>
but what if I have a more complex block like:
<% skill.position.each do |position| %>
<%= position.company.name %>
<% if position.salary? %>
<span><%= position.salary %></span>
<% end %>
<% end %>
The desired output is:
Microsoft, Google 2000, and Yahoo.
Couldn't you just collect it without .each?
<%= skill.positions.collect{ |p| "#{p.company.name}#{position.salary? ? '<span>#{position.salary}</span>' : nil}" }.to_sentence %>
That should work for you...
You could also do this:
<%= skill.position.each do |position| %>
<% position.company.name %>
<% if position.salary? %>
<span><% position.salary %></span>
<% end %>
<% end.to_sentence %>
The to_sentence methods works on Arrays. The reason that it works on your first example...
<%= #blah.collect {|b| b.name}.to_sentence %>
... is because the collect method returns an Array. The each method in your second example will also work because each also returns an Array. So, this will work:
<% blah.each do |b| %>
...
<% end.to_sentence %>

Resources