Display string if null value in db - ruby-on-rails

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.

Related

Rails loop and rowspan

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.

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.

ROR build inserting mutiple records at a time by form

Form screenshot
the image up explain that there is employ who has been allocated three projects at this time he want to full up the fields as he want example he can fill up 2 fields and press submit btn or 1 or 3 depending how many projects he has been assigned.
what i was unable to do is that i want to insert that multiple fields in a table in single submit i do not understand what code i write it will work
the code in my controller is the following.
def new
#pro=Employee.find(params[:employee_id])
#timesheet=Timesheet.new
#project=Project.where(:employee_id => params[:employee_id]).sorted
end
def create
#pro=Employee.find(params[:employee_id])
#timesheet=Timesheet.new(params.require(:timesheets).permit(:employee_id,:project_id,:IN,:comments))
if #timesheet.save
flash[:notice] = "data entered."
redirect_to(:action => 'show',:employee_id =>#pro.id)
else
flash[:notice]="logged out"
end
end
the code in my new.html.erb is the following
<%= form_for(:timesheets, :url => {:action => 'create',:employee_id => #pro.id}) do |d| %>
<% if !#project.nil? %>
<% #project.each do |page| %>
<tr>
<%= d.hidden_field("employee_id" ,:value => #pro.id) %>
<%= d.hidden_field("project_id" ,:value => page.id) %>
<% if !page.employee_id.blank? %>
<td><%= page.prog_name %></td>
<td><%= d.text_field("IN",:class => "qty1") %></td>
<td><%= d.text_field("comments") %></td>
<% end %>
<% end %>
</tr>
<% end %>
<tr>
<td>Total hours</td>
<td colspan="2"><%= text_field_tag("total")%></td>
</tr>
<tr border="0">
<td ><%= submit_tag("Submit") %></td>
<td colspan="2" border="0"></td>
</tr>

Undefined method Error message in Ruby 2.1

I have zero experience with Ruby, and I'm having the following issue:
I receive a "We're sorry, but something went wrong" error message when I try to login into my admin panel (mydomain.com/administrator).
Checking the logs I found out the following:
As well, I checked the login_controller.rb:
Here you have the template:
<h1><%= t(".title")%></h1>
<!-- Pages -->
<% if #pages.length > 0 %>
<h3><%= t(".lastets_pages")%></h3>
<table>
<thead>
<tr>
<th>#</th>
<th><%=t("activerecord.attributes.page.title")%></th>
<th><%=t("activerecord.attributes.page.slug")%></th>
<th><%=t("generic.user_id")%></th>
<th><%=t("generic.created_at")%></th>
<th><%=t("generic.updated_at")%></th>
<th><%=t("generic.actions")%></th>
</tr>
</thead>
<tbody>
<% #pages.each do |page| %>
<tr>
<td><%= page.id %></td>
<td><%= page.title %></td>
<td><%= page.slug %></td>
<td><%= page.user.username %></td>
<td><%= l(page.created_at, format: :long) %></td>
<td><%= l(page.updated_at, format: :long) %></td>
<td class="actions_links">
<%= link_to t("generic.edit"), edit_administrator_page_path(page) %>
<%= link_to t("generic.delete"), administrator_page_path(page), :confirm => t("generic.delete_confirmation"), :method => :delete, class: "delete" %>
</td>
</tr>
<% end %>
</tbody>
</table>
<% else %>
<h3><%= t(".lastets_pages")%></h3>
<div class="alert alert-warning"> <%= t(".lastets_pages_empty")%> </div>
<% end %>
<!-- Notices -->
<% if #notices.length > 0 %>
<h3><%= t(".lastets_notices")%></h3>
<table>
<thead>
<tr>
<th>#</th>
<th><%=t("activerecord.attributes.notice.title")%></th>
<th><%=t("activerecord.attributes.notice.countries")%></th>
<th><%=t("activerecord.attributes.notice.slug")%></th>
<th><%=t("generic.user_id")%></th>
<th><%=t("generic.created_at")%></th>
<th><%=t("generic.updated_at")%></th>
<th><%=t("generic.actions")%></th>
</tr>
</thead>
<tbody>
<% #notices.each do |notice| %>
<tr>
<td><%= notice.id %></td>
<td><%= notice.title %></td>
<td><%= notice.show_countries %></td>
<td><%= notice.slug %></td>
<td><%= notice.user.username %></td>
<td><%= l(notice.created_at, format: :long) %></td>
<td><%= l(notice.updated_at, format: :long) %></td>
<td class="actions_links">
<%= link_to t("generic.edit"), edit_administrator_notice_path(notice) %>
<%= link_to t("generic.delete"), administrator_notice_path(notice), :confirm => t("generic.delete_confirmation"), :method => :delete, class: "delete" %>
</td>
</tr>
<% end %>
</tbody>
</table>
<% else %>
<h3><%= t(".lastets_notices")%></h3>
<div class="alert alert-warning"> <%= t(".lastets_notices_empty")%> </div>
<% end %>
<!-- Faqs -->
<% if #faqs.length > 0 %>
<h3><%= t(".lastets_faqs")%></h3>
<table>
<thead>
<tr>
<th>#</th>
<th><%=t("activerecord.attributes.faq.title")%></th>
<th><%=t("activerecord.attributes.faq.slug")%></th>
<th><%=t("generic.user_id")%></th>
<th><%=t("generic.created_at")%></th>
<th><%=t("generic.updated_at")%></th>
<th><%=t("generic.actions")%></th>
</tr>
</thead>
<tbody>
<% #faqs.each do |faq| %>
<tr>
<td><%= faq.id %></td>
<td><%= faq.title %></td>
<td><%= faq.slug %></td>
<td><%= faq.user.username %></td>
<td><%= l(faq.created_at, format: :long) %></td>
<td><%= l(faq.updated_at, format: :long) %></td>
<td class="actions_links">
<%= link_to t("generic.edit"), edit_administrator_faq_path(faq) %>
<%= link_to t("generic.delete"), administrator_faq_path(faq), :confirm => t("generic.delete_confirmation"), :method => :delete, class: "delete" %>
</td>
</tr>
<% end %>
</tbody>
</table>
<% else %>
<h3><%= t(".lastets_faqs")%></h3>
<div class="alert alert-warning"> <%= t(".lastets_faqs_empty")%> </div>
<% end %>
Notice.rb model:
Can you help me to identify the issue? I tried to clear the cache and nothing happened.
The error backtrace points to the notice.rb:7 file, which is the line inside the block:
countries << country_post.country.name
Undefined method 'name' for nil:NilClass means you are trying to call nil.name, so for a given country_post, country_post.country returns nil.
You'll have to check this part of the code to solve the bug. Another thing you can do is use the try method:
countries << country_post.country.try(:name)
this try method will return country.name if country is not nil, ornil` otherwise:
https://github.com/rails/rails/blob/cd2d3664e3b434d15b6c19e652befb386187642f/activesupport/lib/active_support/core_ext/object/try.rb#L93
https://github.com/rails/rails/blob/cd2d3664e3b434d15b6c19e652befb386187642f/activesupport/lib/active_support/core_ext/object/try.rb#L62
In your Notice.rb model use:
countries << country_post.country.try(:name)
It seems that you are trying to use the notice.show_countries method.
The log is telling you that the method name does not exist for nil, which means that your object is nil.
Please show us the content of the "show_countries" method and please check that you have an acutal object given to the line of code responsible for the method name call.
Have you tried using a debugger ?
UPDATE:
Based on the notice code, your problem is that some post, does not have a coutry, then, country_post.country is nil which result to your error.
Either you ensure that you have a default country at the creation, or you do it in two step when trying to retrieve the information
if country_post.country.blank?
countries << 'DEFAULT_COUNTRY_NAME'
else
country << country_post.country.name
The answer by #mrcasals most directly answers the question and will result in that exception no longer being raised.
However, a more "fundamental" problem here is that you are expecting some data to be persisted to the database which is not. Rails' canonical solution to the problem of ensuring the existence of attributes is via ActiveRecord validations. The general overview is a great read, and the presence validation should do the trick for this problem in particular.

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