Rails по-разному действует в индексе и создает метод - PullRequest
16 голосов
/ 05 сентября 2011

Я строю простой 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

В route.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 просто отлично.

Может кто-нибудь объяснить, что здесь происходит?

Ответы [ 3 ]

38 голосов
/ 15 ноября 2011

После того, как я сам столкнулся с этой проблемой и преодолел ее, я думаю, что смогу дать ответ.

Когда вы просто говорите:

def create
  respond_with({:msg => "success"})
end

rails пытается «угадать» URL-адрес, по которому доступен вновь созданный ресурс, и поместить его в HTTP-заголовок местоположения . Это предположение с треском проваливается для хеш-объекта (местоположение, которое он выводит, равно nil, что приводит к сообщению об ошибке, которое вы видите).

Чтобы преодолеть эту проблему, вам необходимо сделать следующее:

def create
  respond_with({:msg => "success"}, :location => SOME_LOCATION)
end

Предполагая, что вы знаете, где находится новый ресурс. Вы даже можете указать «nil» как «SOME_LOCATION», и это будет работать (несколько нелепо).

1 голос
/ 10 июня 2012

У меня была проблема сама.

Это, как говорит Ауберджин, что-то связанное с заголовком http-местоположения.

На самом деле, рельсы, кажется, строят это местоположение, используя по умолчанию show route.

Если у вас нет show action, - что странно в API, но может случиться (я думаю) `, тогда вы должны установить местоположение самостоятельно.Я понятия не имею, что является стандартом в этом случае.

Если случится так, что вам нужен шоу-маршрут, то закодируйте его, и все должно работать нормально.

Приветствия.

0 голосов
/ 22 марта 2013

Я обнаружил, что errors = {: error => @ device.errors.full_messages} response_with (ошибки,: status =>: bad_request,: location => nil) работает. Расположение: требуется и установка его на ноль помогает при использовании со спецификацией: ожидать (last_response.status). not_to eql 201 ожидать (last_response.location). to be_nil

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...