Rails view: shuffle table column - ruby-on-rails

I am having trouble figuring out how to shuffle table values in a view. I have a table in my view with a left and a right column, and would like to shuffle only the right column.
show.html.erb
<table>
<% #items.each do |item| %>
<tr>
<td><%= item.left %><td>
<td><%= item.right %><td>
</tr>
<% end %>
</table>
The "left" and "right" share the same primary id in the database. Any suggestions about how to shuffle only one side? Thanks!

You can use shuffle, do this way
<% shuffled_items = #items.shuffle %>
<% #items.each_with_index do |item, index| %>
<tr>
<td><%= item.left %><td>
<td><%= shuffled_items[index].right %><td>
</tr>
<% end %>
For details read this documentation http://ruby-doc.org/core-1.9.3/Array.html#method-i-shuffle

I think the simplest way is to have 2 arrays.
#items_left and #items_right
eg:
items = Item.a_scope
#items_left = items
#items_right = items.pluck(:right).shuffle #if you are on > rails 3.2
# #items_left = items.pluck(:left) #if only that attribute is needed
so you can use it as follows
<table>
<% #items_left.each_with_index do |item, i| %>
<tr>
<td><%= item.left %><td>
<td><%= #items_right[i] %><td>
</tr>
<% end %>
</table>

Related

Rails: Highlight the last record inside a loop

I'm trying to highlight the last entry inside a loop. But the following code assigns id="highlight" to every table row :(
<% #sales.order("created_at desc").each do |sale| %>
<tr <% if sale.created_at = Sale.last %>id="highlight"<% end%> >
<td><%= sale.user.name %></td>
<td><%= sale.product %></td>
....
Any ideas? Thank you guys!
if sale.created_at = Sale.last
should be
if sale.created_at == Sale.last.created_at
Alternatively, I guess the following would be better, since it eliminates an additional query Sale.last:
<% #sales.order("created_at desc").each_with_index do |sale, idx| %>
<tr <% if idx == #sales.length - 1 %>id="highlight"<% end%> >
<td><%= sale.user.name %></td>
<td><%= sale.product %></td>
....
HTH
To get the number of rows (without an additional db query), you can use:
#sales.length
Then use each_with_index for your loop:
<% #sales.order("created_at desc").each_with_index do |sale, i| %>
<tr <% if #sales.length == i + 1 %>id="highlight"<% end%> >
<td><%= sale.user.name %></td>
<td><%= sale.product %></td>
</tr>
<% end %>
Check the way you are using the = sign.
Note that equality(==) is different from assignment(=).
What you need is the equality sign(==) here. so:
<% if sale.created_at == Sale.last %>id="highlight"<% end%>
as opposed to:
<% if sale.created_at = Sale.last %>id="highlight"<% end%>
which you are doing.

Rails user defined views

I'm trying to create user defined views in Rails.
I have a uview record for each view. It contains an hstore field called ufields. In ufields I'm storing the names of the columns to be used in the table view.
I can create the table's thead like this:
<thead>
<tr>
<% uview.ufields.each do |key, val| %>
<th><%= key %></th>
<% end %>
</tr>
</thead>
But, how can I define the fields for the tbody.
This doesn't work:
<tr>
<% uview.ufields.each do |key, val| %>
<% ufield = "vehicle." + key %>
<td><%= ufield %></td>
<% end %>
</tr>
That just puts out rows like this vehicle.name.
Is there a way to have this happen? <td><%= vehicle.name %>
This doesn't work, but might give you an idea of what I'm trying to do:
<td><%= <%= ufield %> %></td>
Try:
<% uview.ufields.each do |key, val| %>
<td><%= vehicle[key] %></td>
<% end %>
Actually you could be tempted to do:
vehicle.send key
vehicle.public_send key
But you'd expose to serious flaws since you trust user's inputs
An alternative would be to have in vehicle class:
WHITELISTED_USER_ATTRS = %w(name id) #add what you need but not stuff like destroy etc...
def user_input(key)
if WHITELISTED_USER_ATTRS.include?(key.to_s)
vehicle.send key
else
""
end
end
Then in the view:
<% uview.ufields.each do |key, val| %>
<td><%= vehicle.user_input(key) %></td>
<% end %>

HTML Table issue grabbing data from two database tables

Iam having an issue getting data from two different database tables to display properly with in an HTML table. I'm sure I am just overlooking something and this is pretty easy, but for whatever reason I cannot get quantity to display, or the <td class="sub-total"> to display either.
Demands (you can think of these as orders) and items are connected through a table called demand_items. The demand_items table also has the quantity of the item ordered. The page will display but the quantity and the subtotal will not render.
Here is the html:
<h3>Order for <%= #demand.customer.name %></h3>
<h4>Ordered for: <%= #demand.date %></h4>
<h4>Add Items</h4>
<%= render 'demands/item_form' %>
<table class="customer-table">
<tr>
<th>Item</th>
<th>Price</th>
<th>Quantity</th>
<th>Sub Total</th>
</tr>
<% #demand.items.each do |item| %>
<tr>
<td><%= item.name %></td>
<td><%= item.price %></td>
<% #demand.demand_items do |quantity| %>
<td><%= quantity.quantity %></td>
<td class="sub-total"><%= (item.price) * (quantity.quantity) %></td>
<% end %>
<% end %>
</tr>
</table>
#demand.demand_items.each do |quantity|..........instead of #demand.demand_items do |quantity|......

Rails 3: retrieving different attribute depending on loop count?

I have a loop in one of my views to display a table like so:
Each category object has 5 attributes called: level_1, level_2, level_3, level_4, level_5.
There will be an array with all the category objects. so there could be any amount of categories and no necessarily 3.
what would the best way to draw this up be? i have something like this at the moment but dont know how to select the relevant category level attribute in the 5.times loop.
<table border="0">
<tr>
<th>Maturity</th>
<% for category in #categories %>
<th><%= category.category_title %></th>
<% end %>
</tr>
<% 5.times do |i|%>
<% level = 5 - i %>
<tr>
<td>Level <%= level %> Maturity</td>
<% for category in #categories %>
<td><%= category.level_ #put in the level value here so it selects the relevant attraibute %></td>
<% end %>
</tr>
<% end %>
</table>
you need to change the rendering of level with this:
<% for category in #categories %>
<td><%= category.send("level_#{level}") %></td>
<% end %>
send is used to call a method on an object so that you can compose your method at runtime.
If you categories as variable no. then you shouldn't make it columns, but rows. And then levels will be you columns e.g.
<table>
<tr>
<th>Level 1</th>
<th>Level 2</th>
<th>Level 3</th>
<th>Level 4</th>
<th>Level 5</th>
<tr>
<% #category.each do |c| %>
<tr>
<td>#category.level_1<td>
<td>#category.level_2<td>
<td>#category.level_3<td>
<td>#category.level_4<td>
<td>#category.level_5<td>
<th>
<% end %>
Now in above code you may replace hard coded level_#{no} with iterations.

Rails creating a thumbnail gallery in my view

I currently have an Array that contains some URL's to images.
#images = [ "http://site/images/01.jpg", "http://site/images/02.jpg" ]
Total 18 images
I would like to take this array and create a thumbnail gallery where the gallery is 3 columns across in my view. The HTML out put would be
<table>
<tr>
<td><img src="http://site/images/01.jpg"></td>
<td><img src="http://site/images/02.jpg"></td>
<td><img src="http://site/images/03.jpg"></td>
</tr>
<tr>
<td><img src="http://site/images/04.jpg"></td>
<td><img src="http://site/images/05.jpg"></td>
<td><img src="http://site/images/06.jpg"></td>
</tr>
</table>
My current implementation gets me a one column table
<table>
<tr>
<% #images.each do | image | %>
<td><%= image_tag(image)%></td><br>
<% end %>
</tr>
</table>
In the future I might want it to be 6 columns instead of 3 columns.
I'm looking for a way to do this in a clean and flexible way.
I was looking at the Ruby documentation and I saw this
Class Range (rng.step method)
http://www.ruby-doc.org/core/classes/Range.html
Not sure if this Range class step method can solve the problem but the example it provides is interesting.
Any thoughts, I'm still learning and maybe I'm over thinking this?
use each_slice()
<table>
<% #images.each_slice(3) do |images| %>
<tr>
<% images.each do |image| %>
<td><%= image_tag(image) %></td>
<% end %>
</tr>
<% end %>
</table>
Untested. You need to use each_with_index and the modulus % operator.
<% #images.each_with_index | image, index | %>
<% unless index % column_count == 0 %>
<td><%= image_tag(image)%></td>
<% else %>
<td><%= image_tag(image) %></td>
</tr>
<tr>
<% end %>
<% end %>

Resources