Rails reply_with: как это работает?

Я читал здесь и там о том, как классный метод respond_with находится в Rails 3. Но я даже не могу найти ссылку на него в API Rails или путем поиска источника. Может ли кто-нибудь объяснить мне, как это работает (какие параметры вы можете использовать и т.д.) Или указать мне на место, которое оно действительно реализовало, чтобы я мог самостоятельно прочитать код?

Ответ 1

Код для респондентов основан на классе и модуле. MimeResponds, который включен в ActionController:: Base, класс ваш ApplicationController наследует. Тогда есть ActionController:: Responder, который обеспечивает поведение по умолчанию при использовании response_with.


По умолчанию единственными реляциями поведения, предоставляемыми в ответе, является неявная попытка визуализации шаблона с именем, соответствующим действию. Все, что требуется для этого, требует больше инструкций в действии или пользовательский вызов reply_to с блоком для обработки ответов нескольких форматов.

Поскольку большинство контроллеров используют довольно распространенный шаблон настройки, респонденты обеспечивают дополнительный уровень абстракции, вводя больше поведения по умолчанию. Прочитайте действия, вызывающие to_xml/to_json для определенных форматов, и действия мутаторов, обеспечивающие то же самое, а также перенаправления для успешных действий с мутатором.


Есть несколько возможностей настроить поведение респондентов, от тонких настроек до полного переопределения или расширения поведения.

Уровень класса: respond_to

Здесь вы указываете форматы, которые должен отвечать Ответчик. Форматы могут быть настроены в отношении того, к какому действию они будут применяться. Каждый формат может быть задан с помощью отдельных вызовов, что позволяет полностью настраивать действия для каждого формата.

# Responds to html and json on all actions
respond_to :html, :json

# Responds to html and json on index and show actions only.
respond_to :html, :json, :only => [:index,:show]

# Responds to html for everything except show, and json only for index, create and update
respond_to :html, :except => [:show]
respond_to :json, :only => [:index, :create, :update]

Уровень класса: responder

Это атрибут класса, который содержит ответчика. Это может быть все, что отвечает на вызов, что означает, что вы можете использовать proc/lambda или класс, который отвечает на вызов. Другой альтернативой является смешивание одного или модулей с существующим ответчиком, чтобы перегрузить существующие методы, увеличивая поведение по умолчанию.

class SomeController < ApplicationController
  respond_to :json

  self.responder = proc do |controller, resources, options|
    resource = resources.last
    request = controller.request
    if request.get?
      controller.render json: resource
    elsif request.post? or request.put?
      if resource.errors.any?
        render json: {:status => 'failed', :errors => resource.errors}
      else
        render json: {:status => 'created', :object => resource}
      end
    end
  end
end

Хотя могут быть некоторые интересные варианты использования краев, более вероятно, что расширение или смешивание модулей в ответчик по умолчанию будет более распространенным. В любом случае важными параметрами являются ресурсы и параметры, поскольку они передаются из ответа от response_with.

Уровень экземпляра: respond_with

Здесь перечислены те, которые будут переданы для рендеринга или redirect_to в вашем контроллере, но они включены только для сценариев успеха. Для действий GET это будут вызовы рендеринга, для других действий это были бы варианты для перенаправления. Вероятно, наиболее полезным из них является параметр :location, который может использоваться для переопределения этого пути перенаправления в случае, если аргументов для response_with недостаточно для создания правильного URL-адреса.

# These two are essentially equal
respond_with(:admin, @user, @post)
respond_with(@post, :location => admin_user_post(@user, @post)

# Respond with a 201 instead of a 200 HTTP status code, and also
# redirect to the collection path instead of the resource path
respond_with(@post, :status => :created, :location => posts_path)

# Note that if you want to pass a URL with a query string
# then the location option would be needed.
# /users?scope=active
respond_with(@user, :location => users_path(:scope => 'active'))

В качестве альтернативы, responders gem не только предоставляет некоторые модули для переопределения некоторых по умолчанию. Он переопределяет ответчик по умолчанию с анонимным классом, который расширяет ответчик по умолчанию, и предоставляет метод уровня класса для смешивания в пользовательских модулях этого класса. Наиболее полезным здесь является ответчик вспышки, который предоставляет по умолчанию набор вспышек, делегируя настройку в систему I18n, config/locales/en.yml по умолчанию.

Некоторые примеры пользовательских респондентов, которые я использовал в предыдущих проектах, включают ответчика, который автоматически украшал мои ресурсы, и предоставлял по умолчанию набор названий страниц с интерфейсом для легкой настройки или переопределения названия страницы.