NoMethodError, undefined method 'bid' - ruby-on-rails

Ive been trying to call a helper method from my controller on a rails object and i continue to get this error. Here is all my code.
class AuctionsController < ApplicationController
helper_method :bid
def bid
#auction = #auction.update_attribute(:current_price == :current_price + 1.00)
end
view
<%= link_to("Bid", #auction.bid(auction) )%>
stack trace
Started GET "/auctions" for 127.0.0.1 at 2014-11-11 05:46:16 -0600
Processing by AuctionsController#index as HTML
Auction Load (1.7ms) SELECT "auctions".* FROM "auctions"
Rendered auctions/index.html.erb within layouts/spacelab (199.7ms)
Completed 500 Internal Server Error in 234ms
ActionView::Template::Error (undefined method `bid' for nil:NilClass):
26: <h3, class="textcolor"><%= auction.description %></h3><br />
27: <h3, class="textcolor"><%= auction.start_time.strftime("Opens on %B %d on %I:%M %p") %></h3><br />
28: <h3, class="textcolor"><%= auction.end_time.strftime("Closes on %B %d on %I:%M %p") %></h3><br />
29: <%= link_to("Bid", #auction.bid(auction) )%>
30:
31: <%= link_to 'Show', auction, class: "btn btn-primary btn-lg btn-block" %>
32:
app/views/auctions/index.html.erb:29:in `block in _02d262c45abda05ea87ddc9c2c9ec185'
app/views/auctions/index.html.erb:16:in `_02d262c45abda05ea87ddc9c2c9ec185'
Rendered /Users/claymccullough/.rvm/gems/ruby-2.0.0-p247/gems/actionpack-4.1.6/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (1.0ms)
Rendered /Users/claymccullough/.rvm/gems/ruby-2.0.0-p247/gems/actionpack-4.1.6/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb (0.8ms)
Rendered /Users/claymccullough/.rvm/gems/ruby-2.0.0-p247/gems/actionpack-4.1.6/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb within rescues/layout (92.3ms)
Could anyone tell me if my code is wrong or methodology is incorrect? thanks
edit please see my answer below, that is my real problem...

You have a missundertanding about methods on the controller, you're trying to call a Controller Method on an object, you can't do that. The methods on AuctionsController are part of Controllers no part of the Class, if you want to add operations to a Model class you have to write them in Auction Model
Correct call to your Controller, passing #auction as a parameter
<%= link_to("Bid", #auction )%>

First of all, the error message ActionView::Template::Error (undefined method bid for nil:NilClass) means that you are trying to call a method (bid) on an object that doesn't exist (#auction). Furthermore, the #auction.bid(auction) bit doesn't look good to me either - from a semantics and code-reading point of view but I don't know what you are trying to do exactly.
If you show us the rest of your AuctionsController we will be able to tell you more about what's wrong.

Related

ActionView::Template::Error (undefined method `empty?' for nil:NilClass):

I'm deploying a fairly simple Rails 6.1 app to Heroku. I'm hitting this error on a deploy to Heroku but not locally. I've looked through all the previous posts related to this error, none are actually empty?, they usually are properties on objects that aren't in the database. I can't figure this one out. The error I'm receiving is not related to a database call. My home controller makes no calls to the database, the index page is simple and the error message I'm receiving has to do with path calls built into Rails:
ActionView::Template::Error (undefined method 'empty?' for nil:NilClass):
14: <!-- Inner -->
15: <ul class="sidenav-inner py-1">
16: <li class="sidenav-divider mt-0"></li>
17: <li class="sidenav-item<%= current_page?(root_path) ? ' active' : '' %>">
18: <%= link_to root_path, class: "sidenav-link" do %>
19: <i class="sidenav-icon fad fa-home"></i><div>Home</div>
20: <% end %>`
app/views/layouts/partials/_layout-sidenav.html.erb:17
app/views/layouts/main/layout-without-navbar.html.erb:9
app/views/layouts/main/layout-without-navbar.html.erb:1
My controller:
class HomeController < ApplicationController
def index
#title = 'Home'
end
end
My index page:
<h4 class="font-weight-bold py-3 mb-4">Home</h4>
<p>
This page is an example of basic layout.
</p>
<p>
<button class="btn btn-primary btn-lg">Button</button>
</p>
I've removed the line the error is on (17) and the same error gets thrown on the next line (18) calling root_path.
I've verified that my database migrations have run on Heroku.
I've seeded the Heroku database with sample data for all classes from seeds.rb. I normally wouldn't do this but I wanted to troubleshoot to see if there was an query returning nil somewhere.
I understand what the nil:NilClass error is, I'm attempting to call empty? on a class that's nil. For one, when I do a search through my code there are 0 results for empty? so it must be called in an underlying somewhere. Also, there are no database calls here, and why would a path be nil? I'm starting to feel like this is a red herring error. I am using Devise so I'm curious if it's somehow related to that and I haven't configured something correctly.
Any ideas anyone can give I'd appreciate.
For anyone who may hit this issue, I needed to add the following line in my production.rb file. Add your subdomain.
config.action_mailer.default_url_options = { :host => 'yourdomain.herokuapp.com' }

undefined method `each' for nil:NilClass when using API in Rails

This is obviously a common error. However, I am unable to resolve this issue when going over my code. I am trying to access ProPublica's API for congress. My model, view, and controller is pretty straightforward and this exact code has worked with me when accessing the Google News API.
I keep getting an undefined method error when I try and use the ".each" method in my view to iterate through the JSON response. I believe that I am passing the proper headers to the API as it requests.
My models:
class CongressTracker < ApplicationRecord
include HTTParty
def self.response
#congress = "most recent congress"
#chamber = "one each for congress and senate"
#type = "introduced, passed, etc."
congress_url = "https://api.propublica.org/congress/v1/115/senate/bills/passed.json"
HTTParty.get(congress_url,
:headers => {
"X-API-KEY" => "api-key-here"
})
end
end
class Bill < ApplicationRecord
include HTTParty
end
My controller:
class BillsController < ApplicationController
def index
#response = CongressTracker.response
end
end
My view:
<% #response["results"].each do |bill| %>
<p><%= bill["title"]%></p>
<p><%= bill["summary"]%></p>
<% end %>
My route:
resources :bills
The error in detail:
Rendering bills/index.html.erb within layouts/application
Rendered bills/index.html.erb within layouts/application (2.0ms)
Completed 500 Internal Server Error in 312ms (ActiveRecord: 0.0ms)
ActionView::Template::Error (undefined method `each' for nil:NilClass):
1: <% #response["results"].each do |bill| %>
2: <p><%= bill["title"]%></p>
3: <p><%= bill["summary"]%></p>
4: <% end %>
app/views/bills/index.html.erb:1:in `_app_views_bills_index_html_erb__2110131784793159686_70138696839360'
Example of expected JSON response (which I can get to work in the terminal):
{
"status":"OK",
"copyright":"Copyright (c) 2017 Pro Publica Inc. All Rights Reserved.",
"results":[
{
"congress": "115",
"chamber": "Senate",
"num_results": "20",
"offset": "0",
"bills": [
{
"bill_id": "hr2825-115",
"bill_type": "hr",
"number": "H.R.2825",
"bill_uri": "https://api.propublica.org/congress/v1/115/bills/hr2825.json",
"title": "DHS Authorization Act of 2017",
"summary": "",
},
The reason you are getting the undefined method 'each' for nil:NilClass error, is most likely because the response is {"message"=>"Forbidden"}, because your API key is incorrect.
I tested your code, and everything works correctly as long as you have the correct API key.
You have some mistakes with your view, most likely because you don't have the results yet.
To get the title and the summary of the bills you will need something like this:
<% #response["results"].each do |result| %>
<% result["bills"].each do |bill| %>
<p><%= bill["title"]%></p>
<p><%= bill["summary"]%></p>
<% end %>
<% end %>

How to add an additional View to generated Scaffold and adding an action to it

Hey all I am building out a CAD App in Rails 4 Ruby 2
I apologize if this is a noob question but i'm hung up here..
BACKGROUND
I have my main index page, acting as a multi view dispatch window, currently it Shows Active Pending and Cleared Calls. What I want to add now is a secondary page to list calls with a status of active and that I can eventually add some search fields to to look up previous calls.
my current calls_controller.rb index looks like:
class CallsController < ApplicationController
before_action :set_call, only: [:show, :edit, :update, :destroy]
# GET /calls
# GET /calls.json
def index
#calls = Call.all
#active_calls = #calls.select{|x| x.status == 'ACTIVE'}
#pending_calls = #calls.select{|x| x.status == 'PENDING'}
#clear_calls = #calls.select{|x| x.status == 'CLEAR'}
#approved_calls = #calls.select{|x| x.status == "APPROVED"}
end
**I HAVE THEN ADDED**
def histroy
#calls = Call.all
#approved_calls = #calls.select{|x| x.status == "APPROVED"}
end
I have added a view to the scaffold views and named that view history.hmtl.erb as shown below:
My routes.rb looks like
resources :calls do
collection do
get 'history'
end
end
I then created button to access the the new view:
<%= link_to history_calls_path, class: "btn btn-primary btn-nav", id: 'home-btn' do %>
<i class="fa fa-search"> Call History</i>
<% end %>
When I click the button to access the page i get the following error:
NoMethodError in Calls#history
undefined method `length' for nil:NilClass --> There are already calls with that status but it should return 0 if there are no approved calls
Extracted source (around line #2):
1
2
3
4
5
6
<div class="panel panel-warning" id="clr-calls-pnl">
<div class="panel-heading"><center><h4>Call History -- TOTAL CLEARED CALLS <span class="badge"><%= #approved_calls.length %></span></h4></center></div>
<table class="table" id="approve-table">
<thead>
<tr>
<th><center>Call Number</center></th>
Any help here would be much appreciated as i am still a bit of a noob but have never done this sort of thing before.
Thanks in advance.
EDIT #1:
I changed it to the .try(:lenght)
and now I get this:
NoMethodError in Calls#history
Showing /Users/TaurenLTD1/Desktop/TaurenLabs/PatrolProCAD/PatProCadApp/app/views/calls/history.html.erb where line #31 raised:
undefined method `each' for nil:NilClass
Extracted source (around line #31):
29
30
31
32
33
34
<tbody>
<% #approved_calls.each do |call| %>
<tr>
<td><center><%= call.call_number %></center></td>
<td><center><%= call.site_id %></center></td>
EDIT #2:
This is what the rails log is showing when I Open the History Page:
Started GET "/calls/history" for ::1 at 2015-11-21 19:46:55 -0700
Processing by CallsController#history as HTML
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT 1 [["id", 3]]
Rendered calls/history.html.erb within layouts/application (3.7ms)
Completed 200 OK in 131ms (Views: 129.9ms | ActiveRecord: 0.3ms)
You can use try here.
Change:
<%= #approved_calls.length %>
To:
<%= #approved_calls.try(:length) %>
For some reason your #approved_calls is nil and that's why you got that error. The above should prevent you from getting that error. But, a better approach would be to see why #approved_calls is getting nil value and fix that part and make sure you populate #approved_calls instance variable.
Update
Change your history action to this:
def history
#approved_calls = Call.where(status: 'APPROVED')
end
Final Update
You actually have a typo in your controller action. Change histroy to history.

Ruby on rails Common error: Params missing?

I am building a Order management system. I recently posted a problem about adding a order to a customer. It seems that i have fixed it for 99%. if i look in my terminal it first finds the current customer ID and then creates a new order. The following result is.
Customer Load (0.2ms) SELECT "customers".* FROM "customers" WHERE "customers"."id" = ? LIMIT 1 [["id", 111]]
(0.1ms) begin transaction
SQL (0.4ms) INSERT INTO "orders" ("customer_id", "created_at", "updated_at") VALUES (?, ?, ?) [["customer_id", 111], ["created_at", "2015-11-12 13:28:21.185604"], ["updated_at", "2015-11-12 13:28:21.185604"]]
(8.2ms) commit transaction
But the problem is, it doesn't add the params. I did this intentionally just to check if my syntax would execute the following sql statement. But once i add params i get a common error "param is missing or the value is empty: order"
Here is my code:
Controller
def createorders
#customer = Customer.find(params[:id]) #find current id??
#current_user = Order.find(params[:id])
#orders = #customer.orders.new(order_params)
if #orders.save
flash[:notice] = "Subject created successfully"
redirect_to(:action => 'index')
else
#If save fails, redisplay the form so user can fix problems
render('new') #het zit in de new.html template
end
end
private
def order_params
#same as using "params[:subject]", expect that it:
# - raises an error if :subject is not present
# - allows listed attributes to be mass-assigned
params.require(:order).permit(:pakket, :verstuurt)
end
end
View
<%= link_to("<< Back to List", {:action => 'index'}, :class => 'back-link') %>
<div class="subject new">
<h2>Create Subject</h2>
<%= form_for(:order, :url=> {:action => 'createorders'}) do |f| %>
<table summary="subject form fields">
<tr>
<th>pakket</th>
<td><%= f.text_field(:pakket) %></td>
</tr>
<tr>
<th>verstuurt</th>
<td><%= f.text_field(:verstuurt) %></td>
</tr>
</table>
<div class="form-buttons">
<%= submit_tag("Create Subject") %>
</div>
<% end %>
</div>
Error message
ActionController::ParameterMissing in OrderController#createorders
param is missing or the value is empty: order
Extracted source (around line #107):
105
106
107
108
109
110
def order_params
params.require(:order).permit(:pakket, :verstuurt)
end
end
Serverside Log
Started GET "/order/createorders?id=111" for ::1 at 2015-11-13
11:58:30 +0100 Processing by OrderController#createorders as HTML
Parameters: {"id"=>"111"} Customer Load (0.2ms) SELECT
"customers".* FROM "customers" WHERE "customers"."id" = ? LIMIT 1
[["id", 111]] Completed 400 Bad Request in 5ms (ActiveRecord: 0.2ms)
ActionController::ParameterMissing (param is missing or the value is empty: order): app/controllers/order_controller.rb:107:in
order_params' app/controllers/order_controller.rb:44:in
createorders'
Rendered /Users/cecil/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/actionpack-4.2.4/lib/action_dispatch/middleware/templates/rescues/_source.erb
(8.3ms) Rendered
/Users/cecil/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/actionpack-4.2.4/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (2.6ms) Rendered
/Users/cecil/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/actionpack-4.2.4/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb
(1.3ms) Rendered
/Users/cecil/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/actionpack-4.2.4/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb
within rescues/layout (68.2ms) Rendered
/Users/cecil/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/web-console-2.2.1/lib/web_console/templates/_markup.html.erb
(0.4ms) Rendered
/Users/cecil/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/web-console-2.2.1/lib/web_console/templates/_inner_console_markup.html.erb
within layouts/inlined_string (0.4ms) Rendered
/Users/cecil/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/web-console-2.2.1/lib/web_console/templates/_prompt_box_markup.html.erb
within layouts/inlined_string (0.4ms) Rendered
/Users/cecil/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/web-console-2.2.1/lib/web_console/templates/style.css.erb
within layouts/inlined_string (0.4ms) Rendered
/Users/cecil/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/web-console-2.2.1/lib/web_console/templates/console.js.erb
within layouts/javascript (60.3ms) Rendered
/Users/cecil/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/web-console-2.2.1/lib/web_console/templates/main.js.erb
within layouts/javascript (0.3ms) Rendered
/Users/cecil/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/web-console-2.2.1/lib/web_console/templates/error_page.js.erb within layouts/javascript (0.5ms) Rendered
/Users/cecil/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/web-console-2.2.1/lib/web_console/templates/index.html.erb
(124.2ms)
Thank you stackoverflow for showing me support. I am new with ruby, and i understand i am making noob mistakes. So pointing out flaws are welcome!
I was ignoring your minor, non-fatal issues earlier while I was focused on locating the major issue, but I'll include them now that the major issue is apparent.
First, I'll discuss Rails naming conventions a little bit. You have two models, which are named Customer and Order. You've used the singular form of the noun for these, which is good. Each instance of a model is one thing, so it should be singular. Your controller for the Order model actions, however, should be named with the plural form, so it should be called OrdersController. This is because it controls the actions related to all of your orders. This leads us to your createorders action, which would make a little more sense if it were named createorder, since it only creates one Order. Actually, though, the convention is to name that action create. The action is in your OrdersController, so we already assume that it deals with an Order instance. (When you have Rails automatically generate REST-ful routes for a model's controller with the resources function, it assumes you have an action named create.) Lastly, in your create method, the new Order instance that will be referenced in your view should be called #order instead of #orders, since it contains only one Order.
Now things get a little more complicated. Your param is missing error means exactly that. The parameters for the new Order instance are missing. The request to the server that is producing that error is a GET request that has only one parameter, which you're providing in your URL with ?id=111. Your form's data is not being submitted to the server with that GET request. You should be doing a POST request to create a new Order. I'm going to avoid further exploration (and speculation without seeing your full code) regarding why things aren't working right now and I'll just suggest some key adjustments. It's turning in to a bit a puzzle to figure out how your app works without seeing all of the pieces.
In routes.rb, you should have this line:
resources :customers, :orders
I've made minimal changes to the view you provided, which I assume is called show.html.erb and is in your app/views/customers folder:
<%= link_to("<< Back to List", {:action => 'index'}, :class => 'back-link') %>
<div class="subject new">
<h2>Create Subject</h2>
<%= form_for #order do |f| %>
<table summary="subject form fields">
<tr>
<th>pakket</th>
<td><%= f.text_field(:pakket) %></td>
</tr>
<tr>
<th>verstuurt</th>
<td><%= f.text_field(:verstuurt) %></td>
</tr>
</table>
<%= f.hidden_field :customer_id %>
<div class="form-buttons">
<%= submit_tag("Create Subject") %>
</div>
<% end %>
</div>
Here is the necessary code from customers_controller.rb to support it:
def show
customer = Customer.find params[:id]
#order = customer.orders.new
end
Notice, in the view, the parameter for form_for is the instance that was created in the controller. Also, I've added a hidden field to submit the customer_id with the new Order data.
Finally, your create action in orders_controller.rb might look like this:
def create
#order = Order.new(order_params)
if #order.save
flash[:notice] = "Subject created successfully"
redirect_to(:action => 'index')
else
render 'customers/show'
end
end
And your order_params method should be changed to include the customer_id parameter:
def order_params
params.require(:order).permit(:pakket, :verstuurt, :customer_id)
end
Notice that on a failed save, the action renders customers/show, because this is the page that they were on where the save failed. This will allow Rails to re-populate the form (in the same context) with the data that was present during the failed submission.

Incorrect routing in controller using Rails 4 Autocomplete

I'm following along with this tutorial (http://www.yoniweisbrod.com/autocomplete-magic-with-rails/) using jQuery-ui's autocomplete, but when I attempt to search using the text field, it routes to the controller's show method instead of the autocomplete_ingredient_name method.
Here's the code for my form:
<%= form_tag(cocktail_path(1), :method => 'get', :class => "search_form", :remote => true) do %>
<%= label_tag(:query, "Choose ingredients:") %>
<%= autocomplete_field_tag(:query, params[:query], autocomplete_ingredient_name_cocktails_path, {class: "search-query", placeholder: "", type: "search"}) %>
<% #ingredients.each do |ingredient| %>
<%= hidden_field_tag "ingredients[]", ingredient.name %>
<% end %>
<%= submit_tag("Search") %>
<% end %>
And my controller.
class CocktailsController < ApplicationController
autocomplete :ingredient, :name
def index
#cocktails = []
#ingredients = []
end
def autocomplete_ingredient_name
#ingredients = Ingredient.order(:name).where("name LIKE ?", "'%#{params[:query]}%'")
respond_to do |format|
format.html
format.json {
render json: #ingredients.map(&:name)
}
end
end
def show
hash = {}
#cocktails = []
#ingredients = Ingredient.all.map {|ingredient| ingredient}
#ingredients.select! {|ingredient| ingredient.name.downcase.include?(params[:query])}
if params[:ingredients]
old_ingredients = []
params[:ingredients].each do |ing|
old_ingredients << Ingredient.find_by(name: ing)
end
cocktails = #ingredients.map {|ingredient| ingredient.cocktails }.flatten
old_cocktails = old_ingredients.map {|ingredient| #cocktails << ingredient.cocktails }.flatten!
old_cocktails.each do |cocktail|
hash[cocktail] = 1
end
cocktails.each do |cocktail|
if hash.has_key?(cocktail)
#cocktails << cocktail
end
end
#cocktails = #cocktails.uniq.flatten
else
#cocktails = #ingredients.map {|ingredient| ingredient.cocktails }.flatten
end
end
end
And here is the message from my server, going to the CocktailsController#show method, instead of the autocomplete method.
Started GET "/cocktails/autocomplete_ingredient_name?term=mi" for ::1 at 2015-10-12 15:32:21 -0500
Started GET "/cocktails/autocomplete_ingredient_name?term=mi" for ::1 at 2015-10-12 15:32:21 -0500
Processing by CocktailsController#show as JSON
Processing by CocktailsController#show as JSON
Parameters: {"term"=>"mi", "id"=>"autocomplete_ingredient_name"}
Parameters: {"term"=>"mi", "id"=>"autocomplete_ingredient_name"}
Ingredient Load (8.6ms) SELECT "ingredients".* FROM "ingredients"
Ingredient Load (8.6ms) SELECT "ingredients".* FROM "ingredients"
Completed 500 Internal Server Error in 38ms (ActiveRecord: 8.6ms)
Completed 500 Internal Server Error in 38ms (ActiveRecord: 8.6ms)
TypeError (no implicit conversion of nil into String):
app/controllers/cocktails_controller.rb:25:in `include?'
app/controllers/cocktails_controller.rb:25:in `block in show'
app/controllers/cocktails_controller.rb:25:in `select!'
app/controllers/cocktails_controller.rb:25:in `show'
TypeError (no implicit conversion of nil into String):
app/controllers/cocktails_controller.rb:25:in `include?'
app/controllers/cocktails_controller.rb:25:in `block in show'
app/controllers/cocktails_controller.rb:25:in `select!'
app/controllers/cocktails_controller.rb:25:in `show'
The code is supposed to create a jQuery-ui dropdown that predicts what you're searching, but the dropdown never shows up and it immediately returns a 500 error.
Any thoughts on why this isn't routing to the right method would be extremely appreciated!
This is likely because of a routing error, i.e. your GET "/cocktails/autocomplete_ingredient_name?term=mi" directive is handled by the wrong entry in your /config/routes.rb file.
Make sure the route that handles your autocomplete process is defined prior to the route that handles the show action of your cocktails controller.
Since the latter usually takes the form get 'cocktails/:id', the 'autocomplete_ingredient_name' part of the URI is affected to the :id component and the processing is delegated to the show action of your controller with said id.
The autocomplete route is defined, since the autocomplete_ingredient_name_cocktails_path directive in your form generates a properly formatted URI ; so I believe this is merely an issue of precedence.
You have another potential issue, however: your autocomplete query parameter is 'term' in your request, but it is 'query' in your controller action. They should have the one and same name.

Resources