Using a if statement in a looped table rails - ruby-on-rails

I have two models, one with cards and another with their associated rewards programs. I'm showing all of them in a table with a conditional if statement in some of the columns but I can't figure out why an if else statement screws up my columns. I posted two examples one that works and one that doesn't. I need the second one to work to add some additional functionality
This example works
<table>
<tr>
<th>Card</th>
<th>General Rewards</th>
<th>Gas Amount</th>
<th>Movies Amount</th>
<th>Museums Amount</th>
<th>Theme Park Amount</th>
<th>Restaurant Amount</th>
<th>Department Store Amount</th>
</tr>
<% #cards.each do |card| %>
<tr>
<td><%= card.name %></td>
<td><%= card.general_rate %> </td>
<% card.rewards.each do |category| %>
<% if category.name.downcase == "gas" %>
<td><%= category.threshold_check(#gas) %></td>
<% end %>
<% if category.name.downcase == "movies" %>
<td><%= category.threshold_check(#movies) %></td>
<% end %>
<% if category.name.downcase == "museums" %>
<td><%= category.threshold_check(#museums) %></td>
<% end %>
<% if category.name.downcase == "theme parks" %>
<td><%= category.threshold_check(#theme_parks) %></td>
<% end %>
<% if category.name.downcase == "restaurants" %>
<td><%= category.threshold_check(#restaurants) %></td>
<% end %>
<% if category.name.downcase == "department stores" %>
<td><%= category.threshold_check(#department_stores) %></td>
<% end %>
<% end %>
</tr>
<% end %>
</table>
This adds extra columns to the end
<table>
<tr>
<th>Card</th>
<th>General Rewards</th>
<th>Gas Amount</th>
<th>Movies Amount</th>
<th>Museums Amount</th>
<th>Theme Park Amount</th>
<th>Restaurant Amount</th>
<th>Department Store Amount</th>
</tr>
<% #cards.each do |card| %>
<tr>
<td><%= card.name %></td>
<td><%= card.general_rate %> </td>
<% card.rewards.each do |category| %>
<td><%= category.name.downcase == "gas" ? category.threshold_check(#gas) : 0 %></td>
<td><%= category.name.downcase == "movies" ? category.threshold_check(#movies) : 0 %></td>
<td><%= category.name.downcase == "museums" ? category.threshold_check(#museums) : 0 %></td>
<td><%= category.name.downcase == "theme parks" ? category.threshold_check(#theme_parks) : 0 %></td>
<td><%= category.name.downcase == "restaurants" ? category.threshold_check(#restaurants) : 0 %></td>
<td><%= category.name.downcase == "department stores" ? category.threshold_check(#department_stores) : 0 %></td>
<% end %>
</tr>
<% end %>
</table>

If you will notice the main difference between your 2 versions is that the first one if your conditionals dont comply, you will not issue a <td></td>
On the other hand your second version does have <td></td> no matter if the conditionals are true or not.
Maybe that could be the source for your extra columns.
P.S. In your first example I think you have a typo but <%= category.threshold_check(#movies) %> doesn't have an opening <td> and it's closing </td> is outside the if statement.

Related

Iterate in array of hashes in side array in ruby

I want to iterate this oject and print in table
[
{
:invoice_details=>
{
:customer_name=>"Dylan Sollfrank",
:invoice_number=>"1060",
:invoice_status=>"paid",
:transaction_total_amount=>50.0,
:trnsaction_details=>
[
{
:transaction_number=>"QB1601361635",
:customer_name=>"Dylan Sollfrank",
:amount=> {:amount_to_pay=>50.0, :payment_fee=>0.0},
:created_time=>"12:10 PM",
:created_date=>"Sep 29,2020",
:payment_method=>"Quickbook",
:payment_status=>"completed"
}
]
}
}
]
invoice_details in one row and transaction_details in another row in table format. transaction_details is an array inside the invoice_details.
EDIT
I did it by
I did it
<% ar_activity.first.each do |invoice, invoices_hash| %>
<tr>
<td><%= invoices_hash[:invoice_number] %> </td>
<td><%= invoices_hash[:invoice_status]%></td>
<td><%= invoices_hash[:customer_name] %> </td>
<td><%= invoices_hash[:transaction_total_amount]%></td>
</tr>
<% invoices_hash[:trnsaction_details].each do |transaction|%>
<tr>
<td></td>
<td><%= transaction[:transaction_number]%></td>
<td><%= transaction[:customer_name]%></td>
<td><%= transaction[:amount][:amount_to_pay].to_f + transaction[:amount][:payment_fee].to_f%></td>
<td><%= "#{transaction[:created_time]} " "#{transaction[:created_date]}" %></td>
<td><%= transaction[:payment_method] %></td>
<td><%= transaction[:payment_status] %></td>
</tr>
<%end%>
<%end%>
but its only good for the first invoice_details so it's not working
Thanks
I did it
<% ar_activity.each do |invoices|%>
<% invoices.each do |invoice, invoices_hash| %>
<tr>
<td><%= invoices_hash[:invoice_number] %> </td>
<td><%= invoices_hash[:invoice_status]%></td>
<td><%= invoices_hash[:customer_name] %> </td>
<td><%= invoices_hash[:transaction_total_amount]%></td>
</tr>
<% invoices_hash[:trnsaction_details].each do |transaction|%>
<tr>
<td></td>
<td><%= transaction[:transaction_number]%></td>
<td><%= transaction[:customer_name]%></td>
<td><%= transaction[:amount][:amount_to_pay].to_f + transaction[:amount][:payment_fee].to_f%></td>
<td><%= "#{transaction[:created_time]} " "#{transaction[:created_date]}" %></td>
<td><%= transaction[:payment_method] %></td>
<td><%= transaction[:payment_status] %></td>
</tr>
<%end%>
<%end%>
<%end%>

How to setup restriction for view in a table tag?

This is code of my view file, it shows multiple columns for the table.
The restriction is working but columns are multiple.
<table class="table table-responsive">
<tr>
<th>Title</th>
<th>Description</th>
<% obj.each do |article| %>
<% if logged_in? && current_user == article.user %>
<th>Edit</th>
<th>Show</th>
<th>Delete</th>
<th>Created By</th>
<th>Created At</th>
<th>Updated At</th>
<% end %>
<% end %>
</tr>
<% obj.each do |article| %>
<tr>
<td><%= article.title %></td>
<td><%= article.description %></td>
<% if logged_in? && current_user == article.user %>
<td><%= link_to "Edit", edit_article_path(article), class: "btn btn-primary" %> </td>
<td><%= link_to "show", article_path(article), class: "btn btn-success" %></td>
<td><%= link_to "Delete", article_path(article), method: :delete, data: {confirm: "Are you Sure?"}, class: "btn btn-danger" %></td>
<td> <%= article.user.username if article.user %> </td>
<td> <%= time_ago_in_words(article.created_at) %> ago.</td>
<td> <%= time_ago_in_words(article.updated_at) %> ago.</td>
</tr>
<% end %>
<% end %>
</table>
<%= link_to 'Back', root_path, class: "btn btn-primary btn-lg" %>
You're printing the thead depending on the value of obj, try leaving just the second iteration, to print each tr, maybe something like:
<% if logged_in? && current_user == article.user %>
<tr>
<th>Edit</th>
<th>Show</th>
<th>Delete</th>
<th>Created By</th>
<th>Created At</th>
<th>Updated At</th>
</tr>
<tbody>
<% obj.each do |article| %>
<tr>
<td><%= article.title %></td>
<td><%= article.description %></td>
<% if logged_in? && current_user == article.user %>
<td><%= link_to "Edit", edit_article_path(article), class: "btn btn-primary" %> </td>
<td><%= link_to "show", article_path(article), class: "btn btn-success" %></td>
<td><%= link_to "Delete", article_path(article), method: :delete, data: {confirm: "Are you Sure?"}, class: "btn btn-danger" %></td>
<td> <%= article.user.username if article.user %> </td>
<td> <%= time_ago_in_words(article.created_at) %> ago.</td>
<td> <%= time_ago_in_words(article.updated_at) %> ago.</td>
<% end %>
</tr>
<% end %>
</tbody>
<% end %>
What I understand by your title question, you want to prevent the view of all your table . So
<% if logged_in? && current_user == article.user %>
<table class="table table-responsive">
<tr>
...
the rest of the code for show the table
....
</table>
<% end %>
This will hide the view of the whole table and It only will be shown for the article author
The problem is you're iterating each article in obj and outputting a header each time the currently logged in user is the articles user:
<% obj.each do |article| %>
<% if logged_in? && current_user == article.user %>
<th>Edit</th>
<th>Show</th>
<th>Delete</th>
<th>Created By</th>
<th>Created At</th>
<th>Updated At</th>
<% end %>
<% end %>
You probably only want to show the header a single time if the user is logged in and is the user of any article, Ruby has a method for that, Enumerable#any?. So something like this should be what you're looking for:
<% if logged_in? && obj.any? { |article| current_user == article.user } %>
<th>Edit</th>
<th>Show</th>
<th>Delete</th>
<th>Created By</th>
<th>Created At</th>
<th>Updated At</th>
<% end %>
This should only output one set of the headers if the user is logged in and is the author of any article on the page, instead of one set of headers per article authored.

Rails - Subtotaling based on if statements

<h1> What it looks like currently</h1><br>
<table>
<thead>
<tr>
<th>Month</th>
<th>Month Total</th>
<th>Written</th>
<th>Verbal</th>
<th>Probable 75%</th>
<th>Probable 25%</th>
<th>Speculative</th>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<tr><td>Jan 2017</td> <td>50</td><td>0</td><td>50</td><td>0</td><td>0</td><td>0</td></tr>
<tr> <td>Feb 2017</td> <td>100</td><td>0</td><td>100</td><td>0</td><td>0</td><td>0</td></tr>
<tr><td>Mar 2017</td> <td>700</td><td>0</td><td>700</td><td>0</td><td>0</td><td>0</td></tr>
<tr><td>Jan 2017</td> <td>700</td><td>700</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>
<tr><td>Feb 2017</td> <td>5000</td><td>5000</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>
<tr><td>Jan 2017</td> <td>500</td><td>0</td><td>0</td><td>500</td><td>0</td><td>0</td></tr>
<tr><td>Jan 2017</td> <td>5000</td><td>0</td><td>0</td><td>0</td><td>0</td><td>5000</td></tr>
</tbody>
</table>
<h1> What I need it look like </h1><br>
<table>
<thead>
<tr>
<th>Month</th>
<th>Month Total</th>
<th>Written</th>
<th>Verbal</th>
<th>Probable 75%</th>
<th>Probable 25%</th>
<th>Speculative</th>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<tr><td>Jan 2017</td> <td>1250</td><td>700</td><td>50</td><td>500</td><td>0</td><td>5000</td></tr>
<tr> <td>Feb 2017</td> <td>5100</td><td>5000</td><td>100</td><td>0</td><td>0</td><td>0</td></tr>
<tr><td>Mar 2017</td> <td>700</td><td>0</td><td>700</td><td>0</td><td>0</td><td>0</td></tr>
</tbody>
</table>
I'm a bit of a coding noob so I could be going about this all the wrong way, but I've muddled my way through so far...until now.
What I need is to subtotal the months so the values all appear on the relevant line: Here
The code I used for that is:`
<% #months.each do |t| %>
<tr>
<td><%= t.monthYear %> </td> <td><%= t.monthValue %></td>
<% if(t.destination.status == "Written") %>
<td><%= t.monthValue %></td>
<% else %>
<td>0</td>
<% end %>
<% if(t.destination.status == "Verbal") %>
<td><%= t.monthValue %></td>
<% else %>
<td>0</td>
<% end %>
<% if(t.destination.status == "Probable 75%") %>
<td><%= t.monthValue %></td>
<% else %>
<td>0</td>
<% end %>
<% if(t.destination.status == "Probable 25%") %>
<td><%= t.monthValue %></td>
<% else %>
<td>0</td>
<% end %>
<% if(t.destination.status == "Speculative") %>
<td><%= t.monthValue %></td>
<% else %>
<td>0</td>
<% end %>
</tr>
<% end %>`
The models:
Destination:
class Destination < ActiveRecord::Base
belongs_to :tag
has_many :months
end
Month:
class Month < ActiveRecord::Base
belongs_to :destination
belongs_to :tag
end
The months have 3 fields: monthYear, monthValue & Destination_id.
Destination has Status and others which I don't think are relevant.
I've been searching and used:
% #months.select(:monthYear, :monthValue, :destination_id).group(:monthYear).each do |t| %> and different variations including trying to sum by :monthValue but end up with this: Subtotaled months but not values.
Thanks in advance!
So I figured it out, but the answer definitely isn't pretty! I appreciate this could be done a lot clearer, but I've muddled my way through! Here's the code I used and the result:
View
<tbody>
<% #months.group(:monthYear).each do |z| %>
<% this_thing = 0 %>
<% this_thing2 = 0 %>
<% this_thing3 = 0 %>
<% this_thing4 = 0 %>
<% this_thing5 = 0 %>
<% #testing.each do |b| %>
<% if (z.monthYear == b.monthYear) && (b.destination.status == "Written") %>
<% this_thing = this_thing + b.monthValue %>
<% end %>
<% if (z.monthYear == b.monthYear) && (b.destination.status == "Verbal") %>
<% this_thing2 = this_thing2 + b.monthValue %>
<% end %>
<% if (z.monthYear == b.monthYear) && (b.destination.status == "Probable 75%") %>
<% this_thing3 = this_thing3 + b.monthValue %>
<% end %>
<% if (z.monthYear == b.monthYear) && (b.destination.status == "Probable 25%") %>
<% this_thing4 = this_thing4 + b.monthValue %>
<% end %>
<% if (z.monthYear == b.monthYear) && (b.destination.status == "Speculative") %>
<% this_thing5 = this_thing5 + b.monthValue %>
<% end %>
<% end %>
<td><%=z.monthYear %></td>
<td><%= this_thing + this_thing2 + this_thing3 + this_thing4 + this_thing5 %> </td>
<td><%= this_thing %></td>
<td><%= this_thing2 %></td>
<td><%= this_thing3 %></td>
<td><%= this_thing4 %></td>
<td><%= this_thing5 %></td>
<td><%= (this_thing * 1)+(this_thing2 * 1)+(this_thing3 *0.75)+(this_thing4 * 0.25)+(this_thing5 * 0)%></td>
</tr>
<% end %>
</tbody>
Tags Controller
def index
#months = Month.all
#testing = Month.joins(:destination).includes(:destination).select("months.monthYear, months.monthValue, destination_id, destinations.status")
end
The end result!

Rails summary with sub-totals by date

I'm writing my first Rails view that summarizes data by date. I want one row for each date with the columns summarized for that date.
I have been able to make it work. But, it's awkward coding. This is what I have:
<h3>Carwings Daily Summary</h3>
<table class="display dataTable table table-striped table-bordered" id="dataTable2">
<thead>
<tr>
<th>Date</th>
<th># Trips</th>
<th>E Consumption (kWh)</th>
<th>E Regeneration (kWh)</th>
<th>E Total (kWh)</th>
<th>Distance (Miles)</th>
<th>Energy Economy (Miles/kWh)</th>
<th>CO2 Emission Reduction (lbs)</th>
</tr>
</thead>
<tbody>
<% trips = 0 %>
<% consumption = 0 %>
<% regen = 0 %>
<% total = 0 %>
<% distance = 0 %>
<% economy = 0 %>
<% emissions = 0 %>
<% sumdate = nil %>
<% #carwings.each.with_index do |carwing, index| %>
<% sumdate = carwing.date if index == 0 %>
<% if carwing.date == sumdate %>
<% trips = trips + 1 %>
<% consumption = consumption + carwing.e_consumption %>
<% regen = regen + carwing.e_regen %>
<% total = total + carwing.e_total %>
<% distance = distance + carwing.distance %>
<% economy = economy + carwing.economy %>
<% emissions = emissions + carwing.emission_reduction %>
<% else %>
<tr>
<td class="nowrap"><%= sumdate %></td>
<td><%= trips %></td>
<td><%= consumption %></td>
<td><%= regen %></td>
<td><%= total %></td>
<td><%= distance %></td>
<td><%= economy %></td>
<td><%= emissions %></td>
</tr>
<% trips = 1 %>
<% consumption = carwing.e_consumption %>
<% regen = carwing.e_regen %>
<% total = carwing.e_total %>
<% distance = carwing.distance %>
<% economy = carwing.economy %>
<% emissions = carwing.emission_reduction %>
<% sumdate = carwing.date %>
<% end %>
<% end %>
<tr>
<td class="nowrap"><%= sumdate %></td>
<td><%= trips %></td>
<td><%= consumption %></td>
<td><%= regen %></td>
<td><%= total %></td>
<td><%= distance %></td>
<td><%= economy %></td>
<td><%= emissions %></td>
</tr>
</tbody>
</table>
There's got to be a better way.
Suggestions?
Thanks for the Help!!
Some minor stuff:
trips = trips + 1
# is better written as:
trips += 1
erb tags can be multiline eg:
<% if blah
do_something
something else
end %>
If you are setting multiple variables to the same value, you don't need to repeat them each line eg:
trips = consumption = regen = 0
yes - this is minor stuff - but clean up the minor stuff and it'll give you a better shape of what you're trying to do.
perhaps if you gave us your logic in descriptive pseudocode (so we aren't just guessing what you're trying to do) then we can give you better structure to your code too. :)
Personally: I'd recommend setting up all this data in your controller (or even your carwing model) before it ever hits the view. I'd use a hash - whee the carwnig.date is the key, and all the rest is another hash eg:
data = Hash.new({:trips => 0, :consumption => 0}) # google initialising hashes
#carwings.each do |carwing|
data[carwing.date][:trips] += 1
data[carwing.date][:consumption] += carwing.e_consumption
# etc
end

Rails create new records based on checked records

I have a table showing time entries (events) related to a workorder.
The user can enter a check on any of the table rows.
For each checked row, I want to create a new record in the invtime table.
invtime belongs_to :event
event has_many :invtimes
This is the table:
<table>
<thead>
<tr>
<th>Title</th>
<th>Employee</th>
<th>Date</th>
<th>Hours</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<% Event.where("workorder_id = ?", Invoice.find(#invoice).workorder_id).where("billed = ?", false).each do |event| %>
<tr>
<td><%= check_box_tag(:add_record) %></td>
<td><%= event.title %></td>
<td><%= event.employee.employee_full_name %></td>
<td><%= event.starts_at.strftime("%m/%d/%Y") %></td>
<td><%= event.hours %></td>
<td></td>
</tr>
<% end %>
</tbody>
</table>
I'm not sure how to process the returned page with the checkboxes checked.
Should I use Javascript (coffeescript)? Or can I do it with Ruby?
This should do it:
<tbody>
<%= form_tag(your_path_helper) do %>
<% Event.where("workorder_id = ?", Invoice.find(#invoice).workorder_id).where("billed = ?", false).each do |event| %>
<tr>
<td><%= check_box_tag 'event_ids_to_save[]', value: event.id, checked: Invtime.exists?(event_id: event.id) %></td>
<td><%= event.title %></td>
<td><%= event.employee.employee_full_name %></td>
<td><%= event.starts_at.strftime("%m/%d/%Y") %></td>
<td><%= event.hours %></td>
<td></td>
</tr>
<% end %>
<tr><td colspan='6'><%= submit_tag %></td></tr>
<% end %>
</tbody>
The corresponding action of the controller responding to the form_tag submit:
def action_of_the_form_tag
params[:event_ids_to_save].each do |event_id|
event = Event.where(id: event_id)
# do your logic here
end
end

Resources