1

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?

3
  • Change find_by_id to find ... could be wrong, but my guess is that the row does not exist; if so, find will blow up (properly, as you don't want to continue in this case anyway); find_by_id will just set things to nil, which will non-deterministically blow up somewhere along the way. Commented Apr 20, 2016 at 22:56
  • That definitely worked, please answer below so i can mark it as a solution! thanks so much! By the way, is there a way for find_by_id to 'blow up' so I can get the same error? @GoGoCarl Commented Apr 20, 2016 at 23:01
  • Thanks. See below for details on your second question. find_by_id won't ever blow up, it'll always return nil if the record isn't found. But you can handle that case manually. Commented Apr 20, 2016 at 23:11

1 Answer 1

2

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.