Rails iteration for fields in view - ruby-on-rails

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 %>

Related

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 %>

Get ActiveRecord value with outer index on Rails4

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 %>

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 %>

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 %>

how can i compare the selected values with the existing one in rails

I have a view like this,
<% count = 1 %>
<% for voting in #voting %>
<% if voting.question_id.eql?(count) %>
<%= radio_button( count, voting.vote_count, :radio_id => voting.nominees ) %>
<%= voting.nominees %>
<% end %>
<% if voting.nominees.eql?(radio_id) %>
<% voting.update_attribute('vote_count', voting.vote_count+1 ) %>
<% end %>
<% count += 1 %>
<% end %>
how can i compare the selected nominees with the existing one.
any help on this would be very useful...
Some models and associations would be handy here. I suspect options_from_collection_for_select will be your best friend. Also look at increment.

Resources