Ответ 1
Поскольку ваш маршрут находится в пространстве имен API + v1, вам действительно нужно перенаправить на api_v1_hotel_url(@hotel)
после успешного создания вашего ресурса. Конечно, это API, и нет реального перенаправления, но ответчик Rails по умолчанию этого не знает. Он также не знает о ваших пространствах имен маршрутизации.
Только с ответчиком по умолчанию вам придется делать
respond_with :api, :v1, @hotel
Итак, Rails создаст существующий URL. Кроме того, вы можете создать настраиваемый ответчик, который удаляет параметр :location
. Вот ответчик по умолчанию: http://api.rubyonrails.org/files/actionpack/lib/action_controller/metal/responder_rb.html
Чтение исходного кода для этого класса очень полезно для понимания respond_with
. Например, вам не нужно использовать if record.save
, прежде чем использовать respond_with
с этим ответчиком. Rails проверяет, успешно ли сохранена запись для вас и отображает 422 с ошибками, если она не удалось сохранить.
В любом случае, вы можете видеть, что ответчик устанавливает в него много переменных:
def initialize(controller, resources, options={})
@controller = controller
@request = @controller.request
@format = @controller.formats.first
@resource = resources.last
@resources = resources
@options = options
@action = options.delete(:action)
@default_response = options.delete(:default_response)
end
Если вы подклассифицируете этого ответчика, вы можете сделать что-то вроде этого:
class CustomResponder < ActionController::Responder
def initialize(*)
super
@options[:location] = nil
end
end
Вы можете установить ответчика контроллера с помощью responder=
:
class AnyController < ActionController::Base
self.responder = CustomResponder
# ...
end
Чтобы быть ясным, позвольте мне повторить:
- Когда вы используете
respond_with
, Rails попытается сделать вывод о том, какой маршрут перенаправить после успешного создания. Представьте, что у вас есть веб-интерфейс, где вы можете создавать отели. После того, как отель будет создан, вы будете перенаправлены на эту страницуshow
в стандартном потоке Rails. Вот что делает Rails здесь. - Rails не понимает пространства имен маршрутов при выводе маршрута, поэтому он пытается
hotel_url
- маршрут, который не существует! - Добавление символов перед ресурсом позволит Rails правильно выводить маршрут, в этом случае
api_v1_hotel_url
- В API вы можете создать собственный ответчик, который просто устанавливает предполагаемое местоположение в
nil
, так как на самом деле вам не нужно перенаправлять куда угодно с помощью простого ответа JSON. Пользовательские респонденты также могут быть полезны многими другими способами. Проверьте исходный код.