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 55

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 метод корневого контроллера с форматом называется по умолчанию.

простое, но уродливое решение-переопределить обработку типа контента html для визуализации xml:

   respond_to :html, :xml, :json

   def index
      @regions = Region.all
      respond_with @regions do |format|
        format.html { render :xml => @regions }
      end
    end