Rails: How to name and create unique divs within a loop? - ruby-on-rails

I have a view with a div that is looped many times. Each of the created divs need to have a unique ID so I can access them specifically (at the moment, all my divs have the same ID specified in html so whenever I try to access a specific div it just finds the first one).
This is the version that I currently have (multiple 'rowBox'es are not discernible).
<% #customers.each do |customer| %>
<div id="customer" class="rowBox">
...
</div>
<% end %>
I would like to be able to do something like:
<% #customers.each do |customer| %>
<div id="box<%=customer.id%>">
...
</div>
<% end %>
This doesn't seem to work. Any ideas on how to accomplish this?

Rails has some handy helpers for exactly this.
<% #customers.each do |customer| %>
<%= div_for customer, :class => "rowBox" do %>
...
...
<% end %>
<% end %>
This will produce e.g.:
<div id="customer_1" class="customer rowBox">
...
</div>
<div id="customer_2" class="customer rowBox">
...
</div>
......

<% #customers.each do |customer| %>
<div id=<%= "box#{customer.id}" -%>>
...
</div>
<% end %>
Sorry for earlier omission. This should work.

Related

Using Loop Variable to Set the id Attribute

I have the following code:
<% #electives.each do |elective| %>
<div>
</div>
<% end %>
I would like to set the id of the div to elective.name, but I don't know how to do it, or whether this works:
<% #electives.each do |elective| %>
<div id="elective.name">
</div>
<% end %>
Is it possible to do this in Rails?
Thanks.
You can use <%= ruby variable %> block within erb file to add ruby values within your pages
<div id="<%= elective.name %>">
As an alternative solution, you can use the rails tag helper
<% #electives.each do |elective| %>
<%= tag.div id: elective.name do %>
...
<% end %>
<% end %>

Issue With "Do In Groups of" In Ruby on Rails

I have the following code to display posts in groups of 3 across the page:
<% if #feed_items.any? %>
<% #feed_items.in_groups_of(3).each do |feeds| %>
<div class="row">
<% feeds.each do |feed| %>
<div class="col-md-4">
<ol class="posts">
<%= render feed %>
</ol>
</div>
<% end %>
</div>
<% end %>
<% end %>
It works fine if there are a number of posts that is evenly divisible by 3, however anything not (like 10 posts for example) generates the error "'nil' is not an ActiveModel-compatible object. It must implement :to_partial_path."
Essentially I just want to display my posts so they look like:
Post 1 Post 2 Post 3
Post 4 Post 5
Is there a way to do this with my current code or can someone suggest a non Ruby way of doing this, for example SCSS.
Thanks!
Use Array#compact to remove the nil values:
<% if #feed_items.any? %>
<% #feed_items.in_groups_of(3).each do |feeds| %>
<div class="row">
<% feeds.compact.each do |feed| %>
<div class="col-md-4">
<ol class="posts">
<%= render feed %>
</ol>
</div>
<% end %>
</div>
<% end %>
<% end %>

How to use Bootstrap Scss with Ruby on Rails to style a list of Posts

I'm making a basic Ruby on Rails application where users can make & view posts.
This is the code I use to display posts
<% if #feed_items.any? %>
<ol class="posts">
<%= render #feed_items %>
</ol>
<%= will_paginate #feed_items %>
<% end %>
Currently I have seeded each user with about 50 posts for testing and the posts all display in a list like this:
Post 1
Post 2
Post 3
Post 4 etc
I want to use bootstrap scss to style these posts so instead of the above it is styled more like
Post 1 Post 2 Post 3
Post 4
Where there are 3 posts in each row, rather than just 1.
Does anyone have any suggestions about how someone very new to bootstrap scss could approach this?
You can make use of the combination of in_groups_of and bootstrap grid system
<% if #feed_items.any? %>
<% #feed_items.in_groups_of(3).each do |feeds| %>
<div class="row">
<% feeds.each do |feed| %>
<div class="col-md-4">
<%= render feed %>
</div>
<% end %>
</div>
<% end %>
<% end %>
I think that in_groups_of is a good fit for what you need.
The following code will divide your feed items collection into groups of 3 rows, and then you can format each group of 3 as you like:
<% if #feed_items.any? %>
<table>
<% #feed_items.in_groups_of(3).each do |row_feed| %>
<tr>
<% for feed in row_feed %>
<td><%= feed.title %></td>
<% end %>
</tr>
<% end %>
</table>
<%= will_paginate #feed_items %>
<% end %>

How to display the last third and forth photos with `#photo.last()`

On my user profile, I want to add 4 of the latest photos uploaded by that user. Originally, I had <%- #user.photos.last(4).each do |photo| %>. This code works, but it doesn't work with my layout. So I need one row that displays the last 2 photos, while the second row displays the last 3-4 photos.
Here is what I came up with and the line <%- #user.photos.last(3,4).each do |photo| %> does not work. I've also tried (3-4)
<div class="photo-box">
<%- #user.photos.last(2).each do |photo| %>
<a href="<%= user_photo_path(#user.username, photo.id) %>" class="photo-thumbnail">
<div class="photo-mini">
<%= image_tag photo.url %>
</div>
</a>
<% end %>
</div>
<div class="photo-box">
<%- #user.photos.last(3,4).each do |photo| %>
<a href="<%= user_photo_path(#user.username, photo.id) %>" class="photo-thumbnail">
<div class="photo-mini">
<%= image_tag photo.url %>
</div>
</a>
<% end %>
</div>
You can use the [] method on the photos array.
-1 gets the last element, -2 gets the 2nd to last, and so on.
#user.photos[-2..-1].each #=> return the last two pictures
Of course, you can simply use the #user.photos.last(2).each in this case.
#user.photos[-4..-3].each #=> return the last 3-4 pictures.
This will throw an error unless #user.photos has a length of at least 4, otherwise, you will be trying to access values that does not exist. So, to check for that, you can wrap the div in an if statement.
<% if #user.photos.length >= 2 %>
<div class="photo-box">
<% #user.photos.last(2).each do |photo| %>
...
<% end %>
</div>
<% end %>
<% if #user.photos.length >= 4 %>
<div class="photo-box">
<% #user.photos[-4..-3].each do |photo| %>
...
<% end %>
</div>
<% end %>
I would get the last four in an array, and then divide them into two sets of two using #in_groups_of.
You can then iterate through the two arrays of two photos each to create the divs. This methods easily extends to n groups of m photos.
Something like:
<%- #user.photos.last(4).in_groups_of(2, false).each do |photo_group| %>
<div class="photo-box">
<%- photo_group.each do |photo| %>
<a href="<%= user_photo_path(#user.username, photo.id) %>" class="photo-thumbnail">
<div class="photo-mini">
<%= image_tag photo.url %>
</div>
</a>
<% end %>
</div>

Best practice method of displaying flash messages

I'm wondering what's the best practice for displaying flash messages. The two main ways I've seen are using something like this scaffold generated code
<p id="notice"><%= notice %></p>
or placing code like this in your application header.
<% if !flash.empty? %>
<div id="flash">
<% flash.keys.each do |k| %>
<div class="<%= k %>">
<%= flash[k] %>
</div>
<% end %>
</div>
<% end %>
It appears to me that the first method adds more flexibility while the latter improves code readability and eliminates redundancy. Is there a method most rails developers prefer? As a side question how does scaffolding implement notice? Is it just a helper that accesses the flash hash? Why go through the trouble of using the helper when you can directly use the flash hash? Thanks
I'm doing it this way:
<% flash.each do |key, value| %>
<%= content_tag :div, value, class: "flash #{key}" %>
<% end %>
Calling a partial keeps your application.html.erb even cleaner..
<%= render 'shared/flash_messages' if !flash.empty? %>
.. and in the partial do something like what #zolter mentioned:
<div id="flash_messages">
<% flash.each do |key, value| %>
<%= content_tag(:div, value, :class => "flash #{key}") %>
<% end %>
</div>
Why not put the second method on a helper function so it doesn't affect code readability on layouts?
<% if flash[:notice] %>
<div class="notification is-primary global-notification">
<p class="notice"><%= notice %></p>
</div>
<% end %>
<% if flash[:alert] %>
<div class="notification is-danger global-notification">
<p class="alert"><%= alert %></p>
</div>
<% end %>

Resources