Rails 3 отвечает на: формат по умолчанию?
Я конвертирую приложение Rails 2 в Rails 3. В настоящее время у меня есть контроллер, настроенный следующим образом:
class Api::RegionsController < ApplicationController
respond_to :xml, :json
end
С и действие, которое выглядит следующим образом:
def index
@regions = Region.all
respond_with @regions
end
реализация довольно проста, api / регионы, api / регионы.xml и api / регионы.json все отвечают, как и следовало ожидать. Проблема в том, что я хочу, чтобы api/регионы по умолчанию отвечали через XML. У меня есть потребители, которые ожидают ответа XML, и я бы не хотел их иметь измените все их URL-адреса, чтобы включить .xml, если это не абсолютно необходимо.
в Rails 2 вы бы сделали это, сделав это:
respond_to do |format|
format.xml { render :xml => @region.to_xml }
format.json { render :json => @region.to_json }
end
но в Rails 3 я не могу найти способ по умолчанию использовать ответ XML. Есть идеи?
5 ответов:
Если я понимаю, что вы пытаетесь сделать, вы, вероятно, можете решить эту проблему, установив формат ресурсов по умолчанию в XML. Это позволит вашим пользователям делать запросы с использованием "api / regions" и иметь ответ по умолчанию на XML. Взгляните на разделы "пространства имен и маршрутизация контроллера" и "определение значений по умолчанию" по адресу:
http://guides.rubyonrails.org/routing.html
вы могли бы сделать нечто вроде следующего в маршруты.РБ:
namespace "api" do resources :regions, :defaults => { :format => 'xml' } end
тогда вы должны иметь возможность иметь следующую работу для ваших методов контроллера:
class Api::RegionsController < ApplicationController respond_to :xml, :json def index respond_with(@regions = Region.all) end end
я боролся с этим вопросом сегодня, и я согласился на
before_filter
решение вы упомянули себя в своем комментарии:before_filter :default_format_xml # Set format to xml unless client requires a specific format # Works on Rails 3.0.9 def default_format_xml request.format = "xml" unless params[:format] end
Это решение также позволяет учитывать согласование контента, что было фактором в моем случае. Я хотел, чтобы веб-браузеры получали представление HTML, но пользовательские клиенты (без заголовков Accept) получали JSON. Это решило мою проблему:
before_filter :default_format_json def default_format_json if(request.headers["HTTP_ACCEPT"].nil? && params[:format].nil?) request.format = "json" end end
Не то, что вы после, но связанных:
def index @regions = Region.all respond_to do |format| format.json { render :json => @regions } format.any(:xml, :html) { render :xml => @regions } end end
"ответить также позволяет указать общий блок для разных форматов с помощью любого"
Ну, как вы уже отметили, что каждый формат должен быть явно визуализирован с определенным вызовом рендеринга, вы также можете избежать любого запроса с неизвестным или неподдерживаемым форматом, для моего примера под названием по умолчанию следующим образом:
rescue_from ActionController::UnknownFormat, with: ->{ render nothing: true }
вы можете имитировать вызов неизвестного формата с помощью простого браузера (exmp.firefox) строка (в режиме разработки):
http://localhost/index.default
он позвонит
:index
метод корневого контроллера с форматом называется по умолчанию.