In my home page I iterate over collections of objects, and for each object I render its attributes in a table row. There are four collections of objects, defined as instance variables in my controller, all making Guard (according to the used method) raising one of the following errors:
ActionView::Template::Error: undefined method `each_with_index' for nil:NilClass
ActionView::Template::Error: undefined method `any?' for nil:NilClass
The code in my application view raising the above errors is:
<table class="col-md-4 col-md-offset-1">
<thead>
<tr>
<th> Rank </th>
<th> Gamer </th>
<th> Points </th>
</tr>
</thead>
<tbody>
<% #atp_gamers.each_with_index do |gamer, index| %>
<tr>
<td class="index"> <%= index+1 %> </td>
<td class="gamer"> <%= gamer.name %> </td>
<td class="atppoints"> <%= gamer.atpscore %> </td>
</tr>
<% end %>
<tr class="current-user">
<td> <%= #atp_gamers.to_a.index(current_user) + 1 %> </td>
<td> <%= current_user.name %> </td>
<td> <%= current_user.atpscore %> </td>
</tr>
</tbody>
</table>
<table class="col-md-4 col-md-offset-2">
<thead>
<tr>
<th> Year </th>
<th> Champion </th>
<th> Points </th>
</tr>
</thead>
<tbody>
<% if #atp_champions.any? %>
<% #atp_champions.each do |champion| %>
<tr>
<td class="year"> <%= champion.created_at.year %> </td>
<td class="winnername"> <%= champion.name %> </td>
<td class="winnerpoints"> <%= champion.points %> </td>
</tr>
<% end %>
<% end %>
</tbody>
</table>
The above code is part of a partial (named _gamers_home.html.erb) rendered in the original home page:
<% if logged_in? %>
<% if current_user.gamer? %>
<%= render 'static_pages/gamers_home' %>
<% else %>
<%= render 'static_pages/non_gamers_home' %>
<% end %>
<% else %>
<%= render 'static_pages/non_logged_in_home' %>
<% end %>
The logged_in? method is defined as !current_user.nil?
The instance variables that result nil are: #atp_gamers, #wta_gamers, #atp_champions and #wta_champions, defined in the controller as follows:
def home
if logged_in? && !current_user.gamer?
...l
elsif logged_in? && current_user.gamer?
#gamers = User.where(gamer: true)
#atp_gamers = #gamers.order(atpscore: :desc).limit(50)
#wta_gamers = #gamers.order(wtascore: :desc).limit(50)
#atp_champions = AtpChampion.all
#wta_champions = WtaChampion.all
...
end
end
The first instance variable raising the error (each_with_index' for nil:NilClass) is #atp_gamers. In view I tried to change it with its explicit value, that is User.where(gamer: true).order(atpscore: :desc).limit(50), and the respective code is accepted. After this change, Guard raises an error for #atp_champions.
With rails console #atp_gamers and #wta_gamers are not empty, returning 50 records out of 100 users. #atp_champions and #wta_champions are not nil, but empty arrays.
I suspect that this might be an issue raised only by Guard, because the rails server succeeds in rendering the view.
def home
if logged_in? # delete this line
...
end # delete this line
end
Delete the if logged_in?, and see what happens.
Maybe you have to use before_action :logged_in_user, only :home in controller and define the logged_in_user method as private method.
If non-logged-in users also allowed to access the home action, you need to use if statement erb in the view. Like,
<% if logged_in? %>
<% #atp_gamers.each_with_index do |gamer, index| %>
...
<% end %>
--UPDATE--
Maybe, it needs to toss variables to the partial.
Replace
<%= render 'static_pages/gamers_home' %>
to
<%= render partial: 'static_pages/gamers_home', locals: {atg_gamers: #atp_gamers, wta_gamers: #wta_gamers, atp_champions: #atp_champions, wta_champions, #wta_champions} %>
and, replace the #atp_gamers, #wta_gamers, #atp_champions, #wta_champions in the partial to atp_gamers, wta_gamers, atp_champions, wta_champions.
Try and see what happens.
Related
Here is a index.html.erb. How do I hide the table header, such as Remark, with a method when no records exists in remark attribute column? Preferably without using JavaScript.
index.html.erb
<table id = "kola" class="table listing text-center">
<% has_remark = collection_has_remark?(#aslani361s) %>
<thead>
<tr class="tr-head">
<td>Date</td>
<td>Description</td>
<td>Amount</td>
<td>Discount</td>
<td>Paid</td>
<td>Balance</td>
<td>DelnDel</td>
<% if has_remark %>
<td>Remark</td>
<% end %>
<td>Hide</td>
</tr>
</thead>
</table>
However I am able to hide the remark attribute values like as below ;
_aslani361.html.erb
<% if aslani361.remark.present? -%>
<td class="col-1"><%= aslani361.remark %></td>
<% end %>
aslani361s_helper.rb
module Aslani361sHelper
def collection_has_remark?(collection)
collection.each do |aslani361|
if aslani361.remark.present?
return true
end
end
end
end
aslani361.rb
class Aslani361 < ActiveRecord::Base
end
Any suggestions are most welcome.
Thank you in advance.
If you wish to hide the column because no records in your array has the remark value, you can do something like this:
Define a method in your helper module file for the controller:
def collection_has_remark?(collection)
collection.each do |record|
if record.remark.preset?
return true
end
end
end
Then use it in the view
<% has_remark = collection_has_remark?(#records) %>
<thead>
<tr class="tr-head">
<td>Date</td>
<td>Description</td>
<td>Amount</td>
<td>Discount</td>
<td>Paid</td>
<td>Balance</td>
<% if has_remark %>
<td>Remark</td>
<% end %>
</tr>
</thead>
Then use the same if statement inside your loop. Personally I think it's important to leave an empty column, so users know for sure it doesn't have one.
I've coded in a page in which data from a database is pulled and subsequently when I click on what is displayed it enters a corresponding value into the search function on the application and displays the results, the code can be seen below:
course view:
<!-- Index of all Courses -->
<% provide(:title, "Course") %>
<!--containers for design/layout -->
<div class = "signinstyle">
<div class = "row">
<!--Page information -->
<%= form_tag(degree_new_path, :method => "get", id: "search-data") do %>
<table border="1" class="table">
<thead>
<tr>
<th>Courses</th>
</tr>
</thead>
<tbody>
<% #ads.each do |degree| %>
<tr>
<td> <%= link_to degree.cname, keyword_search_path(search: degree.cname) %>
</td>
</tr>
<% end %>
</tbody>
</table>
<%= submit_tag "Select" %>
<% end %>
<!--closing the design/layout containers -->
</div>
</div>
degree controller (the above view is within this):
class Degree < ActiveRecord::Base
def Degree.search(search)
where("cname LIKE ? OR ucas LIKE ?", "%#{search}%", "%#{search}%")
end
end
search controller (as I use my keyword search in the view):
def keyword_search
#search = Degree.all.select(:uname, :cname, :ucas, :duration, :qualification, :entry).distinct.order(id: :ASC)
if params[:search]
#search_degree = Degree.search(params[:search]).order('cname ASC')
end
end
def course
#select = Degree.all.select(:uname, :cname, :ucas, :duration, :qualification, :entry).distinct.order(id: :ASC)
if params[:search]
#select_degree = Degree.search(params[:search])
end
end
I'm trying to replicate the above code so I can click on similar links which will enter data into the ransack search function I have but have been unable to do so, if anybody could help me out it would be appreciated. Below is the code I'm currently trying to get to work:
Searches controller:
def adsearch
#adsearch = Degree.ransack(params[:q])
#data = #adsearch.result
#adsearch.build_condition if #adsearch.conditions.empty?
#adsearch.build_sort if #adsearch.sorts.empty?
end
the view file:
<!-- Index of all Courses -->
<% provide(:title, "Course") %>
<!--containers for design/layout -->
<div class = "signinstyle">
<div class = "row">
<!--Page information -->
<%= form_tag(degree_new_path, :method => "get", id: "search-data") do %>
<table border="1" class="table">
<thead>
<tr>
<th>Courses</th>
</tr>
</thead>
<tbody>
<% #ads.each do |degree| %>
<tr>
<td> <%= link_to degree.subject_group, adsearch_path(name: ucas & value: degree.ucas_letter) %>
</td>
</tr>
<% end %>
</tbody>
</table>
<%= submit_tag "Select" %>
<% end %>
<!--closing the design/layout containers -->
</div>
</div>
With the last two exerts of code it displays what I'm asking it to display on the initial view but doesn't enter the value I wish it to enter into the ransack search and as such doesn't create a search when clicked upon like the first example does.
What I need to do is create a page where the user will type in a last name and the system will return information related to it. I keep receiving the error "undefined method `each' for nil:NilClass." I am stuck and can not debug it any help or guidance would be greatly appreciated.
CODE FOR THE INPUT PAGE
<%= form_tag(showcustcourses_custcoursesout_path, :controller => "showcustcourses", :action => "custcoursesout", :method => "post") do %>
<div class="field">
<%= label_tag :Customer_Name %><br />
<%= text_field_tag :customer_name_in %>
</div>
<div class="actions">
<%= submit_tag "Submit Customer Name" %>
</div>
<% end %>
CODE FOR THE CONTROLLER
class BookinController < ApplicationController
def bookin
end
def bookout
#customer_name = params[:customer_name_in]
#r = Customer.find_by_last(#customer_name)
#rate_list = #r ? #r.rates : nil
end
end
CODE FOR THE OUTPUT PAGE (<% #customer_list.each do |m| %> is throwing the error)
<h1>Bookin#bookout</h1>
<p>Find me in app/views/bookin/bookout.html.erb</p>
<center><table width = 65% border = 1>
<tr> <th> Customer Name</th><th> Room Number </th> <th> Cost </th></tr>
<% #customer_list.each do |m| %>
<tr> <td> <%= m.name %> </td> <td> <%= m.roomnumber %> </td> <td> <%= m.cost %> </td> </tr>
<% end %>
</table> </center><br /> <br />
You are getting the error undefined method 'each' for nil:NilClass because you forgot to set the value of instance variable #customer_list. So, #customer_list is nil.
You need to set #customer_list variable in the action corresponding to your view which in your case is bookout action as you are rendering bookout.html.erb.
Simply, do this in BookinController#bookout:
def bookout
## ...
#customer_list = Customer.all ## Add this
end
UPDATE
As per the chat discussion, OP needed to show last(from customers table), roomlevel(from apples table), cost(from rates table)
Suggested to modify
bookout method as below:
def bookout
#customer_list = Customer.all
#customer_name = params[:customer_name_in]
end
and bookout.html.erb as below:
<% #customer_list.each do |customer| %>
<% customer.bookings.each do |booking| %>
<tr>
<td> <%= customer.last %> </td>
<td> <%= booking.apple.room_level %> </td>
<td> <%= booking.apple.cost %> </td>
</tr>
<% end %>
<% end %>
Also, OP's schema was not correct to achieve this result. Added apple_id to bookings table and removed rate_id from it.
NOTE: As you don't want bookings to be associated with rates table,rate_idwas removed from bookings table. You would have to add cost field in apples table to display the cost in the view.
Add this in your controller. It will bring details of all customers.
def bookin
#customer_list = Customer.all
end
def bookout
#customer_list = Customer.all
#customer_name = params[:customer_name_in]
#r = Customer.find_by_last(#customer_name)
#rate_list = #r ? #r.rates : nil
end
If still it returns nil error, then it means you do not have any customer records in database.
<h1>Bookin#bookout</h1>
<p>Find me in app/views/bookin/bookout.html.erb</p>
<center><table width = 65% border = 1>
<tr> <th> Customer Name</th><th> Room Number </th> <th> Cost </th></tr>
#check if object is not nil
<% if !#customer_list.nil? %>
<% #customer_list.each do |m| %>
<tr>
<td> <%= m.name %> </td>
<td> <%= m.roomnumber %> </td>
<td> <%= m.cost %>
</td>
</tr>
<% end %>
<% else %>
<p> no customers available </p>
<% end %>
</table>
</center>
#customer_list is not defined
defined it in controller like this
#customer_list = Customer.all
I am trying to display in my a table with most popular tag words, ordered by the count of impression. Then add kaminari to paginate through the records.
in my controller I tried:
#tag_answers = Tag.group(:content).page(params[:page]).order("count_all DESC").count
and in my view:
<table>
<thead>
<th>Tag</th>
<th>Count</th>
</thead>
<tbody>
<% #tag_answers.each do |tag_content, tag_count| %>
<tr>
<td> <%= tag_content %> </td>
<td> <%= tag_count %> </td>
</tr>
<% end %>
</tbody>
</table>
<%= paginate #tag_answers %>
but i am getting the following error
undefined method `current_page' for #<ActiveSupport::OrderedHash:0x000001031b8678>
Try
#tag_answers = Tag.group(:content).select('content, COUNT(*) as count').order("count DESC").page(params[:page])
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.