Rails reply_with действует по-разному по индексу и создает метод
Я создаю простой json API в Rails 3.1. Я создал контроллер, который имеет две функции:
class Api::DogsController < ActionController::Base
respond_to :json, :xml
def index
respond_with({:msg => "success"})
end
def create
respond_with({:msg => "success"})
end
end
В routes.rb у меня есть
namespace :api do
resources :dogs
end
Когда я делаю запрос на получение http://localhost:3000/api/dogs, я получаю правильный json сверху. Когда я делаю сообщение на тот же URL-адрес, я получаю исключение для рельсов:
ArgumentError in Api::DogsController#create
Nil location provided. Can't build URI.
actionpack (3.1.0) lib/action_dispatch/routing/polymorphic_routes.rb:183:in `build_named_route_call`
actionpack (3.1.0) lib/action_dispatch/routing/polymorphic_routes.rb:120:in `polymorphic_url'
actionpack (3.1.0) lib/action_dispatch/routing/url_for.rb:145:in `url_for'
Но если я изменил код создания на
def create
respond_with do |format|
format.json { render :json => {:msg => "success"}}
end
end
он возвращает json просто отлично.
Может кто-нибудь объяснить, что здесь происходит?
Ответы
Ответ 1
Поймав эту проблему сам и преодолев ее, я считаю, что могу дать ответ.
Когда вы просто скажете:
def create
respond_with({:msg => "success"})
end
Какие рельсы пытаются сделать, это "угадать" URL-адрес, который доступен для вновь созданного ресурса, и поместить его в заголовок HTTP location, Это предположение терпит неудачу для хэш-объекта (местоположение, которое оно выводит, равно нулю, что приводит к сообщению об ошибке, которое вы видите).
Чтобы решить эту проблему, вам нужно будет сделать следующее:
def create
respond_with({:msg => "success"}, :location => SOME_LOCATION)
end
Предполагая, что вы знаете, где находится новый ресурс. Вы даже можете указать "nil" как "SOME_LOCATION", и это будет работать (несколько абсурдно).
Ответ 2
У меня была проблема сама.
Это, как говорит Aubergine, связано с заголовком http-адреса.
На самом деле, рельсы, похоже, создают это местоположение, используя по умолчанию show route
.
Если у вас нет show action
, который является странным в API, но может произойти (я думаю) `, то вам нужно установить местоположение самостоятельно. Я понятия не имею, что является стандартом в этом случае.
Если вам повезет, что вам нужен маршрут шоу, тогда введите код, и все должно работать нормально.
Приветствия.
Ответ 3
Я обнаружил, что errors = {: error = > @device.errors.full_messages} response_with (ошибки,: status = > : bad_request,: location = > nil)
работает. Требуется: местоположение и установка его на нуль помогает при использовании с spec: ожидать (last_response.status).not_to eql 201 ожидать (last_response.location).to be_nil
Проблема, с которой я столкнулась, заключается в том, что я не возвращал хеш-ошибки, просто статус. Добавление хэша ошибок и настройка местоположения сами решили.