on my edit action I never rise the record not found if the record does not exist. What I'm doing wrong.
Here is my edit action
class OffersController < ApplicationController
rescue_from ActiveRecord::RecordNotFound, with: :record_not_found
def show
#offer = Offer.find(params[:id])
end
def edit
#offer = Offer.find_by(edit_hash: params[:edit_hash])
#country = Country.find_by(name: #offer.country)
#states = State.find(:all, :conditions => { country_id: #country })
end
private
def record_not_found
render text: "404 Not Found", status: 404
end
end
I always get undefined method `country' for nil:NilClass for my unexist edit record.
Also I raise the record not found on my show action, but I would like to use the 404.html page that I have on my public folder. How can I use this file???
Thanks in advance
The problem is that your line #offer = Offer.find_by(edit_hash: params[:edit_hash]) is not responding with ActiveRecord::RecordNotFound. It's responding with nil.
You can see this by opening up your Rails console from your app's directory with rails c. In the console, put this in:
#offer = Offer.find_by(edit_hash: params[:edit_hash])
You'll see that its output is => nil. You can then type #offer and you'll see its output, again, is => nil. Now, put this line into the console:
#offer = Offer.find(99999)
You'll see that its output is ActiveRecord::RecordNotFound: Couldn't find Offer with id=99999.
To fix the problem, add a ! to your find_by calls, so they are like this:
#offer = Offer.find_by!(edit_hash: params[:edit_hash])
This will cause Rails to respond with ActiveRecord::RecordNotFound: ActiveRecord::RecordNotFound instead of nil.
Related
Rails 5.2
In my inventories_controller.rb, I have the following:
before_action :fetch_product, only: [:show]
def show
........
end
def fetch_product
if params.has_key?(:sku)
#product = Product.get_product(params)
end
end
This works fine, when I do: http://0.0.0.0:3000/sku/12345678
I am trying to implement search functionality, so I modified nventories_controller.rb as follows:
def fetch_product
if params.has_key?(:search) && !params[:search].blank?
product = Product.find_by_sku(params[:search])
if !product
params = params.except[:search]
redirect_to product_show_path, alert: 'Product was not found'
end
params = params.merge!(:sku, product.sku)
end
if params.has_key?(:sku)
#product = Product.get_product(params)
end
end
When I do: http://0.0.0.0:3000/sku/12345678
I get an instant error message:
undefined method `has_key?' for nil:NilClass
Using my debugger, I find that on entry into the fetch_product method, params is nil
Any idea what's going on?
params = params.merge!(:sku, product.sku) modifies the hash in place and returns nil, don't do that assignment, just call params.merge! (if you still want to do the assignment, remove the "!").
Personally, I wouldn't modify the params hash unless it's really really needed, I would use another variable.
Every time I submit the form I get this error: undefined method `each' for nil:NilClass. If everything is correct I can submit the form without any problems, but when there is one thing missing it gives me that error. The error sends me to this line:
views/users/new.html.haml
- #subscriptions.each do |fbs|
= fb.radio_button :subscription_id, fbs.id, class: 'radiobtn', required: true
controllers/users_controller.rb
def new
#user = Users::Business.new
#subscriptions = Businesses::Subscription.all
end
def create
#user = Users::Business.new(user_params)
if #user.save
sign_in(#user)
else
render :new
end
end
Assigns subscriptions in a create action too:
before_filter :set_subscriptions, only: %w(new create) #for edit and update if needed
private
def set_subscriptions
#subscriptions = Businesses::Subscription.all
end
Or add #subscriptions = Businesses::Subscription.all directly to create action after the saving is failed and you re-render new form.
It is happening because there is no value persisted with that model .
You can check the data into the rails console
like ,
$rails console
> Businesses::Subscription.count
And if you see that there is no data then you can write a if ... end block to check for null value and handle it.
I have in my orders/edit.html.erb a form that begins like this:
<%= simple_form_for [#reservation, #order] do |f| %>
Orders Controller:
def edit
#reservation = Reservation.find_by_id(params[:reservation_id])
#order = Order.find_by_id(params[:id])
end
Association:
Reservation :has_one Order
Routes:
resources :reservations do
resources :orders
end
If my path resembles something like /reservations/10/orders/10/edit I end up getting an error from Rails saying NoMethodError in Orders#edit and undefined method 'model_name' for nil:NilClass
When I create a new order the form works perfectly fine so not sure why i'm getting an error all of a sudden, can someone help me with this issue?
Current implementation is prone to failure when the URL supplied either a reservation ID or an order ID that is not valid. Two ways to handle this:
First, let Rails do it for you:
def edit
#reservation = Reservation.find(params[:reservation_id])
#order = Order.find(params[:id])
end
This will raise an ActiveRecord::RecordNotFound error, which, in production, should lead users to your 404 page.
If you'd prefer to keep find_by_id and handle this manually, or to rescue from this error in a different way, you can do:
def edit
#reservation = Reservation.find_by_id(params[:reservation_id])
#order = Order.find_by_id(params[:id])
if #reservation.nil? || #order.nil?
raise ActiveRecord::RecordNotFound.new # Or, do something else
end
end
That would yield the same result as above ... just more code.
I'm working on a rails 4 app, and i have the following controller code
def index
#issue = Issue.find(1)
#sections = #issue.sections
#articles = #issue.articles
end
which breaks if the database is empty with the error: "Couldn't find Issue with id=1". What is the proper way to check for this in a way that if nothing is in the db it doesn't raise an error?
One method you can use is the exists? active record method, like so:
#issue = Issue.where(id: 1)
if #issue.exists?
# do something if it exists
else
# do something if it is missing
end
Side note: Since you're attempting to find by id, you don't necessarily need the .where portion; you can simply do: Issue.exists?(1).
exists? documentation on APIDoc
In most cases such exception is expected and recommenced. For example, you can rescue it with a custom 404 page.
Anyway, if you really don't want that, you can use find_by method which will output nil if nothing found
#issue = Issue.find_by(id: 1)
you can handle that exception in your controller
rescue_from ActiveRecord::RecordNotFound, :with => :record_not_found
def record_not_found
flash[:alert] = "invalid information"
redirect_to root_url
end
or you can use a where clause
#issue = Issue.where(id: 1).first
now check for nil by
#issue.nil?
I am trying to click through a link in my navigation, but an error message appears.
NoMethodError in ViewerController#show
The error points to the following path:
/Users/ianmcdonald/Sites/beatsbymakii/app/controllers/viewer_controller.rb:5:in
`show'
This is the code that I have defined for the method.
class ViewerController < ApplicationController
def show
#page = Page.find_by_name(params[:name])
#subpages = #page.subpages
#pagetitle = #page.title
login_required if #page.admin?
end
end
Please help me as I havent a clue what to do next.
Check whether #page is returned as nil, by outputing it to console like this:
def show
#page = Page.find_by_name(params[:name])
p "#pageeeeeeeee"
puts #page.inspect
#subpages = #page.subpages
#pagetitle = #page.title
login_required if #page.admin?
end
I am almost sure this will be the case as there may not be a page with the specific name in the database.