Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails 3: Why might my respond_to statement throw this exception when called from a POST request?

respond_to :json, :html
.
.
.
return_hash = {}
return_hash[:result] = "valid"
return_hash[:status] = "#{userName} has successfully registered for tournament #{tourneyID}"
respond_with(return_hash) #<--Throwing expection NoMethodError (undefined method `model_name' for NilClass:Class):

Here's the stack trace...

NoMethodError (undefined method `model_name' for NilClass:Class):
app/controllers/tournaments_controller.rb:48:in `register'

Rendered /Users/myname/.rvm/gems/ruby-1.9.2-p180/gems/actionpack-3.0.5/lib/action_dispatch/middleware/templates/rescues/_trace.erb (2.8ms)
Rendered /Users/myname/.rvm/gems/ruby-1.9.2-p180/gems/actionpack-3.0.5/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb (151.8ms)
Rendered /Users/myname/.rvm/gems/ruby-1.9.2-p180/gems/actionpack-3.0.5/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb within rescues/layout (211.1ms)

Thanks so much!

Not sure if it matters, but I should add this is called in response to a POST request

Update: I have similar code that works fine, it looks like this...

 # Store the tourney data
 tourney_hash[:tournament_count] = 1
 tourney_hash[:tournament_id] = nextTourney.id
 tourney_hash[:remaining_time_in_seconds] = remainingTimeInSeconds   
 respond_with(tourney_hash)

The only difference is this code is called from a GET request, while the problematic code above is called from a POST request

UPDATE: When I changed this code so that it's called from a GET request instead of a POST request, it works fine. Your thoughts?

UPDATE: For the time being, I've replaced the statement "respond_with(return_hash)" with "render :json => return_hash.to_json" and it works fine. Not ideal, tho.

like image 341
BeachRunnerFred Avatar asked Dec 27 '22 21:12

BeachRunnerFred


2 Answers

due to http://apidock.com/rails/ActionController/MimeResponds/respond_with

respond_with(*resources, &block) public

It means that respond_with method accepts resource(s) while return_hash is a hash, not an ActiveRecord object. So your code is wrong. It won't ever work.

UPD

Why does this work with GET and doesn't work with POST, PUT or DELETE?

I don't know why do you use so strange construction as respond_with(some_hash). What is respond_with method?

respond_with wraps a resource around a responder for default representation

So it is strange to pass not resource but hash.

Now let's understand how it works:

# GET request
respond_with(whatever)
# same as
respond_to do |format|
  format.html{ } # will render your_action_name.html.erb
end

BUT!

# POST request
respond_with(whatever)
# is same as
respond_to do |format|
  format.html{ redirect_to WHATEVER } # !!!!
end

That's how respond_with works

So you should pass a resource to respond_with but not anything else. So your approach was wrong. And that is why you have got an error. Because to redirect_to return_hash it tries to get its model_name to generate a path.

That's it.

UPD 2

To render json you should:

respond_to do |format|
  format.json{ render :json => return_hash.to_json }
end
like image 81
fl00r Avatar answered Jan 14 '23 04:01

fl00r


I believe respond_with is supposed to be used with an ActiveRecord object (or a collection of ActiveRecord objects), not a hash.

like image 20
Dylan Markow Avatar answered Jan 14 '23 03:01

Dylan Markow