Rails 3: Почему мой оператор response_to может выдавать это исключение при вызове из POST-запроса?

#ruby-on-rails #ruby-on-rails-3

#ruby-on-rails #ruby-on-rails-3

Вопрос:

 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):
  

Вот трассировка стека…

 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)
  

Большое спасибо!

Не уверен, имеет ли это значение, но я должен добавить, что это вызывается в ответ на POST-запрос

Обновить:У меня есть аналогичный код, который отлично работает, он выглядит следующим образом…

  # 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)
  

Единственное отличие в том, что этот код вызывается из запроса GET, в то время как проблемный код, приведенный выше, вызывается из запроса POST

ОБНОВЛЕНИЕ: Когда я изменил этот код так, чтобы он вызывался из запроса GET вместо запроса POST, он работает нормально. Ваши мысли?

ОБНОВЛЕНИЕ: На данный момент я заменил оператор «response_with(return_hash)» на «render : json => return_hash.to_json», и он работает нормально. Хотя и не идеально.

Комментарии:

1. ради любопытства, делает ли это то же самое, если вы используете переменную экземпляра?

2. да, это так. когда я пытаюсь вернуть var временного экземпляра со значением 10, хранящимся в нем, я получаю это исключение «NoMethodError (неопределенный метод model_name' for Fixnum:Class): app/controllers/tournaments_controller.rb:50:in register’ »

3. как вы определяете model_name и userName

4. я определяю userName как ‘userName = params[:username]’, а model_name — это всего лишь часть описания ошибки

5. Я не могу воспроизвести вашу ошибку, здесь работает нормально (я использую Ruby Enterprise Edition, а вы?)

Ответ №1:

из-за http://apidock.com/rails/ActionController/MimeResponds/respond_with

response_with(*ресурсы, amp; блок) общедоступный

Это означает, что respond_with метод принимает ресурс (ы), пока return_hash является хэшем, а не объектом ActiveRecord. Итак, ваш код неверен. Это никогда не сработает.

UPD

Почему это работает с GET и не работает с POST, PUT или DELETE?

Я не знаю, почему вы используете такую странную конструкцию, как respond_with(some_hash) . Что такое respond_with метод?

respons_with обертывает ресурс вокруг ответчика для представления по умолчанию

Поэтому странно передавать не ресурс, а хэш.

Теперь давайте поймем, как это работает:

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

НО!

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

Вот как respond_with работает

Итак, вы должны передать ресурс respond_with , но не что-либо еще. Итак, ваш подход был неправильным. И именно поэтому вы получили ошибку. Потому что redirect_to return_hash он пытается получить его model_name для генерации пути.

Вот и все.

UPD 2

Для рендеринга json вам следует:

 respond_to do |format|
  format.json{ render :json => return_hash.to_json }
end
  

Комментарии:

1. У меня есть очень похожий код, который возвращает хэш с использованием response_with, и он отлично работает, пожалуйста, смотрите мой обновленный вопрос выше. Спасибо!

2. Я только что обновил свой вопрос, упомянув, что код работает нормально, когда он выполняется в ответ на запрос GET вместо запроса POST. Ваши мысли?

3. что находится в строке 48? tournaments_controller.rb:48

4. return_hash[:результат] = «действительный»

5. извините, оператор в строке 48 ‘response_with(tourney_hash)’

Ответ №2:

Я полагаю, respond_with предполагается использовать с объектом ActiveRecord (или коллекцией объектов ActiveRecord), а не с хэшем.

Комментарии:

1. У меня есть очень похожий код, который возвращает хэш с использованием response_with, и он отлично работает, пожалуйста, смотрите мой обновленный вопрос выше. Спасибо!

2. Я только что обновил свой вопрос, упомянув, что код работает нормально, когда он выполняется в ответ на запрос GET вместо запроса POST. Ваши мысли?