How to add a delimiter/separator to a Rails block - ruby-on-rails

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

Related

Interpret string value as ruby method

I have a FormQuestion model that stores form_for tags as strings.
I am looking to have something like the following:
<%= form_for(application_form) do |f| %>
<% FormQuestion.all.each do |q| %>
<%= q.input %> #where q.input = "f.text_field :name"
<% end %>
<% end %>
How can I get the string returned from q.input to be interpreted as the form_for ruby tag, rather than simply being printed as text on the page?
EDIT:
eval(q.input) was suggested, however I am looking for a safer alternative
You can use send method as:
<%= form_for(application_form) do |f| %>
<% FormQuestion.all.each do |q| %>
<%= f.send(q.input) %> #where q.input = "f.text_field :name"
<% end %>
<% end %>
I would change this to either be:
<%= form_for(application_form) do |f| %>
<% FormQuestion.all.each do |q| %>
<% f.send q.type, q.name %> #where q.type = :text_field and q.name = :name
<% end %>
<% end %>
Or else:
<%= form_for(application_form) do |f| %>
<% FormQuestion.all.each do |q| %>
<%= raw q.as_html %> # where q.as_html = "<input name="name"></input>"
<% end %>
<% 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 %>

Having labels only appear once in field_for

What I currently have is:
<%= f.label :attachment_uploader, 'Current Attachments:' %>
<%= f.fields_for :data_files do |attachment| %>
<% if !attachment.object.new_record? %>
<%= attachment.label :attachment_uploader, 'Delete: ' + attachment.object.attachment_uploader_url.split("/").last %>
<%= attachment.check_box :_destroy %>
<% end %>
<% end %>
However, if I don't have any attachments the label is still there. For the sake of aesthetics I'd like it to be hidden unless I have attachments.
I was thinking something akin to:
<%= f.fields_for :data_files do |attachment, index| %>
<% if index == 0 %>
<%= attachment.label :attachment_uploader, 'Current Attachments:' %>
<% end %>
#rest of code
<% end %>
But that doesn't work!
I've read about the f.options[:index] in another post, but I couldn't figure it out.
Add an unless empty? condition before fields_for. #object will be the object for which you created the form
<%= f.label :attachment_uploader, 'Current Attachments:' %>
<% unless #object.data_files.empty? %>
<%= f.fields_for :data_files do |attachment| %>
<% if !attachment.object.new_record? %>
<%= attachment.label :attachment_uploader, 'Delete: ' + attachment.object.attachment_uploader_url.split("/").last %>
<%= attachment.check_box :_destroy %>
<% end %>
<% 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