Issue With "Do In Groups of" In Ruby on Rails - 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 %>

Related

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>

Create new Bootstrap row every third array item

I have an array of #schools (School.all), and I am displaying these #schools within a Bootstrap row (3 per row). I was wondering how I could make it so that for every third item in #schools, Ruby/Rails would create a new row and then repeat that process. Thanks.
<% for 3 in #schools %>
<div class="row">
<% #schools.each do |s| %>
<div class="col-md-4">
</div>
<% end %>
</div>
<% end %>
each_slice is your friend.
<% #schools.each_slice(3) do |schools| %>
<div class="row">
<% schools.each do |s| %>
<div class="col-md-4">
</div>
<% end %>
</div>
<% end %>
<% #schools.in_groups_of(3) do |schools| %>
<div class="row">
<% schools.each do |s| %>
<div class="col-md-4">
</div>
<% end %>
</div>
<% end %>
For documentation: http://apidock.com/rails/Array/in_groups_of

Dynamically generate all products on a responsive view using Bootstrap's Grid system

I want to generate all my products and their information on a page using bootstrap's grid system. I tried to generate three products in a row at first and it worked using the following code:
<div class="container">
<h1 align="center">Listing products</h1>
<% #products.each do |product| %>
<% if #a%3 == 0 %>
<div class="row">
<% end %>
<div class="col-lg-4">
<%= image_tag(product.image_url, class: 'list_image', size: '260x320') %>
<%= product.title %> <br/>
<%= product.price %> <br/>
<%= link_to 'Show', product %><br/>
</div>
<% #a = #a+1 %>
<% if #a%3 == 0 %>
</div><hr/>
<% end %>
<% end %>
</div>
(#a is what I declared in the controller which is initially set to 0)
The code will not work anymore if I want to only display two or less products in a row using the grid system when the screen gets smaller.
Are there any better ideas to achieve this?
Seems like you are generating incorrect HTML markup. Try to use each_slice:
<div class="container">
<h1 align="center">Listing products</h1>
<% #products.each_slice(3) do |products| %>
<div class="row">
<% products.each do |product| %>
<div class="col-lg-4">
<%= image_tag(product.image_url, class: 'list_image', size: '260x320') %>
<%= product.title %> <br/>
<%= product.price %> <br/>
<%= link_to 'Show', product %><br/>
</div>
<% end %>
</div>
<hr/>
<% end %>
</div>

Is it possible to display two columns side by side in a Rails view, using Bootstrap, when looping through 'projects'?

I'm using Bootstrap 3 with Rails 4.0.0. Currently this is my index.html.erb for Projects:
<div class="col-lg-6">
<% #projects.each do |project| %>
<h3>
<%= project.name %>
</h3>
<% end %>
</div>
When a user adds lots of new projects, I would like to limit the length of the page and display additional 'projects' on the right hand column. So I would like to have two columns side by side. In html it would be just the following, but how can I make it work in Rails?
<div class="row">
<div class="col-lg-6">Projects...</div>
<div class="col-lg-6">Projects....</div>
</div>
You can use each_slice:
<% #projects.each_slice(<your_limit_per_column>) do |projects| %>
<div class="col-lg-6">
<% projects.each do |project| %>
<h3>
<%= project.name %>
</h3>
<% end %>
</div>
# First half of projects
<div class="col-lg-6">
<% #projects.first(#projects.length/2).each do |project| %>
<h3>
<%= project.name %>
</h3>
<% end %>
</div>
# Second half of projects
<div class="col-lg-6">
<% #projects.last(#projects.length /2 + #projects.length % 2).each do |project| %>
<h3>
<%= project.name %>
</h3>
<% end %>
</div>

Resources