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
Related
I'm getting an error when trying to link_to a patient profile when a provider views his patients list. I have no problem displaying all the names of the patients that belong to the provider but when trying to link to the patient profile I get an undefined method 'id'.
So the way it works is, patients can search for providers and add them to the List model. On the provider side, I just list out all the patients that added that specific provider. Here is my erb code below,
<div class="body">
<div class="body">
<% if #active_patients.count > 0 %>
<table>
<thead>
<tr>
<th>Patient Name</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<% #active_patients.each do |list| %>
<tr>
<td>
<%= list.patient.role.user.first_name %> <%= list.patient.role.user.last_name %>
</td>
<td>
<%= link_to patient_path(id: #patient.id), class: "btn" do %>View<% end %> . #### THIS IS THE LINE
</td>
</tr>
<% end %>
</tbody>
</table>
<% else %>
<div class="no-records">
<%= image_tag "icon-no-records", class: "image" %>
<div class="text">You have no patients.</div>
</div><!--no-records-->
<% end %>
</div><!--body-->
</div>
Here is my List model,
class List < ApplicationRecord
belongs_to :membershipable, :polymorphic => true
belongs_to :provider
def patient
membershipable_type=='Patient' ? membershipable : nil
end
def provider_user
patient.try(:user)
end
end
Also here's the error message ->
Let Rails do the work of building the path. Each ActiveRecord model has a to_param method which decides how the instance will be encoded in an URL. By default it returns the model id but it could also be a slug based on the title or another property of the model.
Calling your helper like patient_path(patient) should do the trick.
Additionally, in your current code, you're referring to the previously unused #patient variable, even though it looks like you want to refer to list.patient instead.
Here:
<% #active_patients.each do |list| %>
<tr>
<td>
<%= list.patient.role.user.first_name %> <%= list.patient.role.user.last_name %>
</td>
<td>
<%= link_to patient_path(id: #patient.id), class: "btn" do %>View<% end %> . #### THIS IS THE LINE
</td>
</tr>
<% end %>
you have the variable list available to you. It appears that you get the patient by doing list.patient, as you do here:
<%= list.patient.role.user.first_name %> <%= list.patient.role.user.last_name %>
But, then you try to use a variable called #patient, here:
<%= link_to patient_path(id: #patient.id), class: "btn" do %>View<% end %> .
when you don't have the variable #patient. So, you get your nil error.
Instead, it seems you should do:
<%= link_to patient_path(id: list.patient.id), class: "btn" do %>View<% end %> .
Or, as milgner points out, you could simply do:
<%= link_to patient_path(list.patient), class: "btn" do %>View<% end %> .
Also, you might want to look into the Law of Demeter, which you violate (IMO) when you do:
list.patient.role.user.first_name
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.
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.
It's a simple question.
For example, I have 3 data
number name country
1 Jack US
2 Coda UK
3 Fredy TW
How do I display this number in rails dynamically.
here is part of code
<% #stay_times.each do |s| %>
<tr>
<td>
<%#= I don't know what to put here %>
</td>
<td>
<%= s.name %>
</td>
<td>
<%= s.nationality %>
</td>
<% end %>
Also you can use each_with_index method:
<% #stay_times.each_with_index do |s, index| %>
<tr>
<td>
<%= index + 1 %> <!-- index starts with zero -->
</td>
<td>
<%= s.name %>
</td>
<td>
<%= s.nationality %>
</td>
<% end %>
each_with_index(*args) public
Calls block with two arguments, the item and its index, for each item
in enum. Given arguments are passed through to #each().
If no block is given, an enumerator is returned instead.
hash = Hash.new
%w(cat dog wombat).each_with_index {|item, index|
hash[item] = index
}
hash #=> {"cat"=>0, "dog"=>1, "wombat"=>2}
It looks like you just need to use <%= s.number %> for the line where you have a comment. It depends on what the number field in the data table is called in your #stay_times variable. Hope this helps!
I'm looping through each instance of a built sub-tournament - and the problem that I'm having has to do with conditionally creating a collection_select box with data fetched via ajax. Here's the view - the line I want to insert code in is marked:
View
<% #tournament.sub_tournaments.each_with_index do |sub, i| %>
<%= f.fields_for :sub_tournaments, sub, :validate => false do |sub_form| %>
<div class="tab-content standings-row-<%= i %>" style="display:none">
<table>
<thead>
<tr>
<th> <h4>Standing</h4> </th>
<th class="standings-field-<%= i %>"></th>
<th></th>
</tr>
</thead>
<tbody>
<%= sub_form.fields_for :standings, :validate => false do |standings| %>
<tr>
<td>
<%= f.hidden_field :_destroy %><%= f.text_field :standing, :class => "standing", readonly: true, :type => "" %>
</td>
<td class="standings-ajax-<%= i %>">**INSERT HERE**</td>
<td><span class="remove">Remove</span></td>
</tr>
<% end %>
</tbody>
</table>
<div class="add-item">
<%= link_to_add_standings_fields(sub_form, :standings) %>
</div>
</div>
<% end %>
<% end %>
I thought about doing the conditional check (it depends upon whether the game selected is a team game or a single-player game) in the controller, but it seems to make more sense as a method (or a helper?). At the moment I have it in Standing.rb (below) - but I'm getting a no method "collection_select" error - so probably form helpers aren't available in models, which seems reasonable. So how could I do this?
Standing.rb
def team_or_player(game)
if Game::TEAM_GAMES.include?(game.name)
self.collection_select(:team_division_id, TeamDivision.where("game_id = ?", game.id),
:id, :name, {include_blank: true})
else
self.collection_select(:player_id, Player.where("game_id = ?", game.id),
:id, :handle, {include_blank: true})
end
end
And how can I pass the f to my AJAX call?
AJAX
$(".standings-ajax-<%= #tab_number %>").html("<%= ** ?? **.team_or_player(#standing, #game) %>");
You can call helper in model:
ActionController::Base.helpers.collection_select( ... )
So from what I can see you should change team_or_player() to class method and call it with:
Standings.team_or_player(#standing, #game)
or as instance
#standing.team_or_player(#standing, #game)
But that you should use self instead of passing #standing.
Me preference would be to put that logic directly in view or to helper.