Loop multiple variable to form one table - ruby-on-rails

What would be the best method to loop multiple variables into one table? Each variable could have one or more data points. For example, I wish to create something like this:
The following code example is only placing each item in a row.
<table class="table">
<% (#variable1 + #variable2 + #variable3).each do |data, v2, v3| %>
<tr>
<% if data.is_a?(Variable1) %>
<td><%= data.date %></td>
<td><%= data.name %></td>
<% elsif data.is_a?(Variable2) %>
<td><%= data.date %></td>
<td><%= data.name %></td>
<% elsif data.is_a?(Variable3) %>
<td><%= data.date %></td>
<td><%= data.name %></td>
<% end %>
</tr>
<% end %>
</table>

In this case, since you don't know how many records might be in each array, I would find out the greatest length of the arrays I have.
In your controller for this aciton could do something like:
#max_length = [#variable_1, #variable_2, #variable_3].map(&:size).max
*Note: this assumes those variables are always arrays, even if they only have a length of 1.
Then in your view file you could do this:
<table class="table">
<% #max_length.times do |n| %>
<tr>
<td><%= #variable_1[n].try(:date) %></td>
<td><%= #variable_1[n].try(:name) %></td>
<td><%= #variable_2[n].try(:date) %></td>
<td><%= #variable_2[n].try(:name) %></td>
<td><%= #variable_3[n].try(:date) %></td>
<td><%= #variable_3[n].try(:name) %></td>
</tr>
<% end %>
</table>
This way, for the third row, for example, in columns 1 and 3 in your example there will be no values, but values for the second column, which has a third record, will appear.

Related

has_many loop undefined method

I have a has_many association in which I want to display in a table. Each Agent can make up to 3 sales, but I want to list them in the same row as the Agent.
undefined method `each' for nil:NilClass on the <% sales.each do |s| %> line.
I'm getting the above error, event though there is defiantly data present for each column
<table>
<tr>
<td>Agent</td>
<td>Date</td>
<td>Product</td>
<td>Price</td>
<td>Date</td>
<td>Product</td>
<td>Price</td>
<td>Date</td>
<td>Product</td>
<td>Price</td>
</tr>
<% #agent.sales.each do |agent, sales| %>
<tr>
<td><% agent.name %></td>
<% sales.each do |s| %>
<td><%= s.date %></td>
<td><%= s.product %></td>
<td><%= s.price %></td>
<% end %>
</tr>
<% end %>
</table>
To start, since #agent.sales is an ActiveRecord_Associations_CollectionProxy, you can think of this object more like an array, rather than a hash.
How you initially wrote your loop it appears you were treating it like a hash:
#agent.sales.each do |agent, sale| > this syntax is saying for each key-value pair in the hash, do something with the key (agent) and value (sale).
The second time you try to run a loop, you're running it on the "value" part of the iterator, which does not exist, hence the error on the line sales.each do |sale|
Really, you are very close but are overthinking it. Just drop your first iterator and keep the rest:
<tr>
<td><% #agent.name %></td>
<% #agent.sales.each do |s| %>
<td><%= s.date %></td>
<td><%= s.product %></td>
<td><%= s.price %></td>
<% end %>
</tr>
By the way, you can apply the same principle and refactor your headers too:
<tr>
<td>Name</td>
<% 3.times do |n| %>
<td>Date</td>
<td>Product</td>
<td>Price</td>
<% end %>
</tr>
This assumes that your constraint is 3 max sales.
This should work:
<table>
<tr>
<td>Agent</td>
<td>Date</td>
<td>Product</td>
<td>Price</td>
<td>Date</td>
<td>Product</td>
<td>Price</td>
<td>Date</td>
<td>Product</td>
<td>Price</td>
</tr>
<% #agent.sales.each do |sale| %>
<tr>
<td><% #agent.name %></td>
<td><%= sale.date %></td>
<td><%= sale.product %></td>
<td><%= sale.price %></td>
</tr>
<% end %>
</table>

render all records in a stored procedure

I am trying to render all the data of a stored procedure in a table in my view but the problem is that the name of the columns can change in each stored query so I can not make the specific field call in the render because each query brings different columns, how could I make the call of the columns name for the (table titles) and render all the data in the unspecified in the name of the data but bring all the results of the query that apparently returns them in an array?
this is my stored_procedures_controller.rb
class StoredProceduresController < ApplicationController
before_action :authenticate_usuario!
def cantidad_productosxpedido
#cantidad_productosxpedido = Stored_procedure.fetch_db_records("exec SPAD_ReporteProductosxPedido '#{Time.now.try(:strftime,"%Y%m%d")}','#{params[:search]}','#{params[:search6]}'")
respond_to do |format|
format.html
format.js
format.xls
end
end
end
this is my model stored_procedure.rb
class Stored_procedure < ActiveRecord::Base
def self.fetch_db_records(proc_name_with_parameters)
connection.select_all(proc_name_with_parameters)
end
def self.insert_update_delete_calculate(proc_name_with_parameters)
connection.execute(proc_name_with_parameters)
end
def self.fetch_val_from_sp(proc_name_with_parameters)
connection.select_value(proc_name_with_parameters)
end
end
I usually do the rendering of the stored this way
<table class="table table-striped table-bordered table-condensed table-hover rwd_auto">
<thead>
<tr>
<th>Ruta</th>
<th>Pedido</th>
<th>IdCliente</th>
<th>Cliente</th>
<th>Nombre Comercial</th>
<th>2010100</th>
<th>2020100</th>
<th>2020200</th>
<th>2020500</th>
<th>2021200</th>
<th>2200500</th>
<th>2200501</th>
<th>2200508</th>
<th>2200509</th>
<th>2201000</th>
<th>2203100</th>
<th>2203101</th>
<th>2203102</th>
<th>2203104</th>
<th>2203108</th>
<th>2203200</th>
</tr>
</thead>
<tbody id="container_productosxpedido">
<%= render partial: "/stored_procedures/cantidad_productoxpedido", collection: #cantidad_productosxpedido %>
</tbody>
</table>
and in the partial _cantidad_productoxpedido
<tr>
<td><%= cantidad_productoxpedido['Ruta'] %></td>
<td><%= cantidad_productoxpedido['Pedido'] %></td>
<td><%= cantidad_productoxpedido['IdCliente'] %></td>
<td><%= cantidad_productoxpedido['Cliente'] %></td>
<td><%= cantidad_productoxpedido['NombreCorto'] %></td>
<td><%= cantidad_productoxpedido['2010100'] %></td>
<td><%= cantidad_productoxpedido['2020100'] %></td>
<td><%= cantidad_productoxpedido['2020200'] %></td>
<td><%= cantidad_productoxpedido['2020500'] %></td>
<td><%= cantidad_productoxpedido['2021200'] %></td>
<td><%= cantidad_productoxpedido['2200500'] %></td>
<td><%= cantidad_productoxpedido['2200501'] %></td>
<td><%= cantidad_productoxpedido['2200508'] %></td>
<td><%= cantidad_productoxpedido['2200509'] %></td>
<td><%= cantidad_productoxpedido['2201000'] %></td>
<td><%= cantidad_productoxpedido['2203100'] %></td>
<td><%= cantidad_productoxpedido['2203101'] %></td>
<td><%= cantidad_productoxpedido['2203102'] %></td>
<td><%= cantidad_productoxpedido['2203104'] %></td>
<td><%= cantidad_productoxpedido['2203108'] %></td>
<td><%= cantidad_productoxpedido['2203200'] %></td>
</tr>
but when changing the name of the columns I do not know how to do to display the data without specifying the names of those columns
UPDATE
I could resolve to display the contents of the table as follows
<%#cantidad_productosxpedido.to_a.each do |foo|%>
<tr>
<%foo.each do |label, value|%>
<td><%= value %></td>
<%end%>
</tr>
<%end%>
but now I try to add the headers of the table
like this:
<%#cantidad_productosxpedido.first.each do |foo|%>
<tr>
<%foo.each do |label, value|%>
<th><%= label %></th>
<%end%>
</tr>
<%end%>
but it does not show correct in the table but renders it as follows
<tr>
<th>title1</th> <td>value1</th>
</tr>
<tr>
<th>title2</th> <th>value2</th>
</tr>
object.attributes.keys will return an array of column names for a given record. You can use that to generate your columns as follows:
<% #cantidad_productosxpedido.each do |cantidad_productoxpedido| %>
<% cantidad_productoxpedido.keys.each do |col| %>
<td><%= cantidad_productoxpedido[col] %></td>
<% end %>
<% end %>
Not tested, but that should work.

How to get unique elements through array and group them in ruby on rails

i have issue. This below code is the views code of ruby in rails
<table >
<tr>
<th>Url</th>
<th>Tags</th>
</tr>
<% #array_bookmark = #bookmark.class == Array ? #bookmark : [#bookmark] %>
<% Array(#bookmark).each do |book| %>
<tr>
<td><%= book.url %></td>
<td><%= book.tags %></td>
</tr>
<% end %>
</table>
This yields something like :
Url Tags
www.mrabhiram.tumblr.com abhi
www.mrabhiram.tumblr.com blog
google.com google
google.com blog
But, i want to get it as
Url Tags
www.mrabhiram.tumblr.com abhi,blog
google.com google,blog
Can anyone provide me the solution? It should be generic enough to iterate over the array.
Thank you in advance.
<% Array(#bookmark).group_by {|b| b.url}.each do |url, books| %>
<tr>
<td><%= url %></td>
<td><%= books.map {|b| b.tags}.flatten.uniq.join(" ") %></td>
</tr>
<% end %>
Use group_by statement
upd
<% Array(#bookmark).group_by(&:url).each do |url, books| %>
<tr>
<td><%= url %></td>
<td><%= books.map(&:tags).flatten.join(',') %></td>
</tr>
<% Array(#bookmark).uniq.each do |book| %>
<tr>
<td><%= book.url %></td>
<td><%= book.tags %></td>
</tr>
<% end %>
the above will work.

Trying not to repeat myself with Rails data manipulation

I'm fairly new to rails, an an intermediate programmer in general, but I'll try to be as clear as I can.
I have a database table for Products, which owns a field called category. Category has two possible values, call them Category1 and Category 2. The goal is to retrieve all the Products and display them in HTML organized by Category. I can make this work, but I know there has to be a better way.
My method now is to get my Products like so:
#category1_products = Product.all(conditions: { category: "Category1" })
#category2_products = Product.all(conditions: { category: "Category2" })
and then output the data something like this:
<table>
<tr>
<td>Category1 Name</td>
<% #category1_products.each do |product| %>
<td><%= product.name %></td>
<td><%= product.description %></td>
<td><%= product.price %></td>
<% end %>
</tr>
<tr>
<td>Category2 Name</td>
<% #category2_products.each do |product| %>
<td><%= product.name %></td>
<td><%= product.description %></td>
<td><%= product.price %></td>
<% end %>
</tr>
</table>
I would like to accomplish this using a single instance: get all Products at once, group them by Category, and then output them by looping through one Category at a time (including the Category Names). This seems like a pretty elementary concept to me, but I'm having trouble getting my head around it.
#products_by_category = Product.all.group_by(&:category)
This is a Ruby (read: not ActiveRecord) method to turn an Array into a Hash based on some condition of the objects it contains.
In your view (assuming you want one row per product, and not one per category):
<table>
<% #products_by_category.each do |category,products| %>
<tr>
<th><%= category %></th>
</tr>
<% products.each do |product| %>
<tr>
<td><%= product.name %></td>
<td><%= product.description %></td>
<td><%= product.price %></td>
</tr>
<% end %>
<% end %>
</table>
Rails' group_by is great for this type of problem:
#grouped_products = Product.all.group_by(&:category)
and then in the view, just loop over #grouped_products:
<table>
<tr>
<% #grouped_products.each do |category, products| %>
<td><%= category %></td>
<% products.each do |product| %>
<td><%= product.name %></td>
<td><%= product.description %></td>
<td><%= product.price %></td>
<% end %>
<% end %>
</tr>
</table>

Getting info to insert from a belongs_to relationship

I've got orders, which have many line items, and line items which belong to products. I'm trying to extract the product title, but it's not appearing in the output. I'm getting the line_item info fine. They are all linked in the line_items table, which has both order_id and product_id fields. I'm pretty new to rails, please can someone help me figure out where I'm going wrong?
<% #order.line_items.each do |line_item| %>
<tr>
<% line_item.product do |product| %>
<td><%= product.title %></td>
<% end %>
<td><%= number_to_currency(line_item.price) %></td>
<td><%= line_item.quantity %></td>
<td><%= number_to_currency((line_item.price*line_item.quantity))%></td>
</tr>
<% end %>
Try:
<% #order.line_items.each do |line_item| %>
<tr>
<td><%= line_item.product.title %></td>
<td><%= number_to_currency(line_item.price) %></td>
<td><%= line_item.quantity %></td>
<td><%= number_to_currency((line_item.price*line_item.quantity))%></td>
</tr>
<% end %>

Resources