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

Проблема, с которой я столкнулась, заключается в том, что я не возвращал хеш-ошибки, просто статус. Добавление хэша ошибок и настройка местоположения сами решили.