Rails loop and rowspan - ruby-on-rails

I'm having issues with rowspan in a loop in my form using conditional statements. My first Rowspan 2 is outside the loop and works fine, but my second Rowspan 2 is inside the conditional, therefore it does not work as it should. Is there a method to resolve this?
This is what I'm trying to achieve
Form
<table>
<th>Header 1</th>
<th>Header 2</th>
<th>Description</th>
<th>Phase</th>
<tr>
<td rowspan="4">Rowspan 4</td>
<td rowspan="2">Rowspan 2</td>
<% Identity.all.each do |identity| %>
<%= form.fields_for :indicators, form.object.indicators.where(identity: identity).first_or_initialize do |ff| %>
<%= ff.hidden_field :id %>
<%= ff.hidden_field :identity_id %>
<% if ff.object.identity.number <= 1.4 %>
<td><%= ff.object.identity.description %></td>
<td><%= ff.collection_select :phase_id, Phase.all, :id, :name %></td>
</tr>
<tr>
<% elsif ff.object.identity.number > 1.4 %>
<td rowspan="2">Rowspan 2</td>
<td><%= ff.object.identity.description %></td>
<td><%= ff.collection_select :phase_id, Phase.all, :id, :name %></td>
<% end %>
</tr>
<% end %>
<% end %>
</table>

This is definitely doable, but I think it's not working for you based on how you're partitioning the data.
Specifically, it seems like you're closing trs in weird places, as well as you create one rowspan outside the loop.
A more robust solution would likely partition the data into rowspan=X blocks (maybe by using group_by, in_groups_of, chunk)
<table>
<tr>
<th>Header 1</th>
<th>Header 2</th>
<th>Description</th>
<th>Phase</th>
</tr>
<tr>
<td rowspan="4">Rowspan 4</td>
<% Identity.all.each_with_index do |identity, index| %>
<% if index.positive? %>
<tr> #emit a tr in every row but the first
<% end %>
<% if index.even? %>
<td rowspan="2">Rowspan 2</td>
<% end %>
<%= form.fields_for :indicators, form.object.indicators.where(identity: identity).first_or_initialize do |ff| %>
<%= ff.hidden_field :id %>
<%= ff.hidden_field :identity_id %>
<td><%= ff.object.identity.description %></td>
<td><%= ff.collection_select :phase_id, Phase.all, :id, :name %></td>
</tr> #Close a tr in every row
<% end %>
<% end %>
</table>
I haven't tested this personally, but I think something closer to this format would work. It would also be useful to see the html output you're actually getting to debug.

Related

Rails 5 ActiveRecord Update Serialized Array in Form

I have a field that is a serialized array. It's loaded into my model and accessed in a form:
class Site < ApplicationRecord
serialize :steps, Array
end
<table class="listing" summary="Site list">
<tr class="header">
<th>Name</th>
<th>Step 1</th>
<th>Step 2</th>
<th>Step 3</th>
<th>Actions</th>
</tr>
<% #sites.each do |site| %>
<tr>
<td><%= site.name %></td>
<% site.steps.each do |step| %>
<td><%= step %></td>
<% end %>
<td class="actions">
<%= link_to("Show", site_path(site), :class => 'action show') %>
<%= link_to("Edit", edit_site_path(site), :class => 'action edit') %>
<%= link_to("Delete", delete_site_path(site), :class => 'action delete') %>
</td>
</tr>
<% end %>
</table>
I'm trying to update my edit form so that I can edit each "step" in the array.
<%= form_for(#site) do |f| %>
<table summary="Site form fields">
<tr>
<th>Name</th>
<td><%= f.text_field(:name) %></td>
</tr>
<% a=1 %>
<% #site.steps.each do |step| %>
<tr>
<th>Step <%= a %>
<td><%= text_field :site, :steps, :value => step %></td>
<% a += 1 %>
</tr>
<% end %>
</table>
<div class="form-buttons">
<%= f.submit("Update Site") %>
</div>
<% end %>
The edit form displays the steps field correctly as each individual string in the array. However, when I attempt to submit the form I get the following error:
Attribute was supposed to be a Array, but was a String.
So steps is being submitted as the last entry in the array. How can I display the form correctly and also present the updated array back to the controller for processing?
Your text_field would need to multiple set to true. I believe in your case, something like this should work.
<%= f.text_field(:steps, { multiple: true, value: #site.steps[step] }) %>

How to create a non-static HTML table header and rows

I have two arrays, and I'd like to create a table with dynamic header cells (from the first array called subjects) and iteratively add contents (from the second array called examscores) in table rows with respect to the table header value.
Desired outcome is (fiddle):
The erb code is:
<table width="100%" border="1">
<thead>
<tr>
<th rowspan="2" scope="col">NAME</th>
<th colspan="<%= #subjects_by_class.size %>" scope="col">Subjects/Scores</th>
<th rowspan="2" scope="col">Total</th>
<th rowspan="2" scope="col">Average</th>
</tr>
<tr>
<% #subjects_by_class.each do |s| %>
<th> <%= s.name %></th>
<% end %>
</tr>
</thead>
<tbody>
<% #examscore.each do |ex| %>
<tr>
<td><%= get_student_name_by_id(ex.student_id) %></td>
<% #subjects_by_class.each do |ss| %>
<% #examscore.each do |ii| %>
<% if ss.id == ex.subject_id %>
<td> <%= i.total %> </td>
<% break %>
<% end %>
<% end %>
<% end %>
<td><%= sum_student_totalscore(ex.student_id, year_id) %> </td>
<td><%= avg_student_totalscore(ex.student_id, year_id) %></td>
</tr>
<% end %>
</tbody>
</table>
The output I get is (fiddle):
A new tr is created under Maths subject instead of a new td for Arts subject, and this results in Average td being distorted.
Any insight will be greatly appreciated.
Well, just look at this section of your code:
<% #examscore.each do |ex| %>
<tr>
You create a new line for each #examscore, and you have 4 of those (1 per user/subject, so you end up with 4 lines of course).
Your tbody should be something like this:
<tbody>
<% #students.each do |student| %>
<tr>
<td><%= student.name %></td>
<% #subjects_by_class.each do |subject| %>
<% #examscore.each do |score| %>
<% if score.subject_id == subject.id && score.student_id == student.id %>
<td><%= score.total %></td>
<% break %>
<% end %>
<% end %>
<% end %>
<td><%= sum_student_totalscore(student.id, year_id) %> </td>
<td><%= avg_student_totalscore(student.id, year_id) %></td>
</tr>
<% end %>
</tbody>
It's a bit strange that you only care about the year in your totals
Also you could improve things a little bit by having a method in your Student class that returns an array of scores for a given year/list of subjects
# Returns an array of scores for the given year
def scores(year, subject_ids)
subject_ids.map do |subject_id|
# find score for year & the given subject_id
end
end
This way your body would become
<tbody>
<% #students.each do |student| %>
<tr>
<td><%= student.name %></td>
<% #scores = student.scores(year_id, #subjects_by_class) %>
<% #scores.each do |score| %>
<td><%= score.total %></td>
<% end %>
<% scores_total = #scores.sum(&:total) %>
<td><%= scores_total %> </td>
<td><%= scores_total / #scores.size.to_f %></td>
</tr>
<% end %>
</tbody>
which I found more clear, but it could be further improved with decorators for instance.

param is missing or the value is empty: record

Hi I am using Ruby on Rails to show an table, this is the code in view:
<h1> Show by category</h1>
<h2> table </h2>
<table border="1" style="width:70%">
<tr>
<th>Name</th>
<th>SKU</th>
<th>Category</th>
<th><%= link_to "New",new_record_path %>
</tr>
<%= #records.each do |r| %>
<tr>
<td><%= r.name %></td>
<td><%= r.sku %></td>
<td><%= r.category %></td>
<td><%= link_to "Edit", edit_record_path(r) %></td>
</tr>
<% end %>
<%= will_paginate #records %>
</table>
and I got this
http://i.stack.imgur.com/rUN0v.png
Between the headline and the table, the records are all shown up, I don't know where it is coming from, can somebody help?
The problem is here in this line
<%= #records.each do |r| %>
which should be
<% #records.each do |r| %>
Imp note:
<% %> #Executes the statement/expression.
<%= %> #Prints the output.

Display string if null value in db

I have the following table which displays the results of a match and the selections for that match for the signed in user. I want to display a text value in the selection.winner and selection.value columns when there is no related record found in the database but I am unsure how to do this. My code is as follows:
<% Fixture.where(:weekno => #gameweek.number).each do |fixture| %>
<tr>
<td width="10"><%= fixture.date.strftime("%d/%m/%Y")%></td>
<td width="10"><%= fixture.date.strftime("%H:%M") %></td>
<td width="80"><%= fixture.home_team %></td>
<td width="10">Vs.</td>
<td width="80"><%= fixture.away_team %></td>
<td width="10"><%= fixture.result %></td>
<% Selection.where(:userid => current_user.id, :fixtureno => fixture.id).each do |selection| %>
<td width="10"><%= selection.winner %></td>
<td width="10"><%= selection.value %></td>
<% end %>
</tr>
<% end %>
Do you want to display any string if the database field is nil??
If yes you can use,
<%= selection.winner || 'string' %>
<%= selection.value || 'string' %>
You can put the results of the Selection lookup into a variable and test against that:
<% user_selections = Selection.where(:userid => current_user.id, :fixtureno => fixture.id) %>
<% if user_selections.empty? %>
<td>You have no selections for this match.</td>
<% else %>
<% user_selections.each do |selection| %>
<td width="10"><%= selection.winner %></td>
<td width="10"><%= selection.value %></td>
<% end %>
<% end %>
I've put a <% and %> on each line because I think it is clearer. You could just use one for each block of code though, for example:
<% else
user_selections.each do |selection| %>
I'm not sure how many user selections you have for a particular fixture but this will find them all so if there's loads you'll get them all which will cause poor performance AND a massive row in your table. You know your data better than me though, maybe there's a limit on user selections.

ruby-on-rails iterating through object attributes in view template aka .erb file

I'm using ruby on rails.
wondering if this is achievable.
Original Code
<%= form_for(:page, :url=>{:action => 'create'}) do |f| %>
<table summary="Subject Form Fields" %>
<tr>
<th>Name</th>
<td><%= f.text_field(:name) %></td>
</tr>
<tr>
<th>Position</th>
<td><%= f.text_field(:position) %></td>
</tr>
<%end%>
desired code something along the lines of creating forms
by iterating through the object attributes.
<% for attribute in #subject.attributes.keys %>
<tr>
<td><%= attribute.humanize %></td>
<td><%= #subject.attributes[attribute].to_s %></td>
</tr>
<% end %>
so I am not sure if this is possible.
I believe what you are looking for is a .each loop:
<% #subject.attributes.each do |attribute| %>
<%= attribute.humanize %>
<% end %>
That will loop through each attribute of the #subject. If you also want to loop through the keys of each attribute, you need to add another nested loop:
<% #subject.attributes.each do |attribute| %>
<% attribute.keys.each do |key| %>
<%= attribute.humanize %> or <%= key %>
<% end %>
<% end %>
Hope that helps.

Resources