Rails response_with: як це працює?


128

Я читав тут і там про те, наскільки класний respond_withметод в Rails 3. Але я навіть не можу знайти посилання на нього в API Rails або в пошуку джерела. Чи може хто-небудь пояснити мені, як це працює (які параметри ви можете використовувати тощо), або вказати мені на місце, де воно реально реалізовано, щоб я міг вивчити код самостійно?

Відповіді:


128

Оновлення для Rails 4.2+

#respond_withі ::respond_to( метод класу nb ) більше не є частиною Rails . Вони були перенесені в дорогоцінне каміння сторонніх респондентів станом на Rails 4.2 ( примітки до випуску / зобов’язання від серпня 2014 року). Хоча респонденти не включені до Rails за замовчуванням, це залежність від Devise і тому доступна у багатьох програмах Rails.

Спосіб #respond_to екземпляра, однак, все ще є частиною Rails (5.2rc1 станом на цей текст).

Офіційна документація API Rails ActionController::MimeRespondsпояснює, як #respond_toпрацює. Оригінальна документація щодо Rails Guides коментує #respond_withі ::respond_toдосі її можна знайти у вихідному коді дорогоцінного коду відповідачів .


Оригінальний відповідь

Код для респондентів базується на класі та модулі. MimeResponds, який входить до ActionController :: Base , класу, від якого ви ApplicationControllerуспадковуєте. Потім з'являється ActionController :: Responder, який забезпечує поведінку за замовчуванням при використанні respo_with.


За замовчуванням єдиною рейкою поведінки, що надається у відповіді, є неявна спроба надати шаблон із назвою, що відповідає дії. Все, що виходить за рамки цього, вимагає додаткових інструкцій в межах дії або спеціального дзвінка_відповідача з блоком для обробки відповідей у ​​кількох форматах.

Оскільки більшість контролерів використовують досить поширену схему налаштування, респонденти надають додатковий рівень абстракції, вводячи більше поведінки за замовчуванням. Прочитайте дії, що викликають 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

Хоча можуть бути цікаві випадки використання крайових ситуацій, більш імовірно, що розширення або змішування модулів у відповіді за замовчуванням буде більш поширеними моделями. У будь-якому випадку, релевантними є ресурси та параметри, оскільки вони передаються з відвідки_відвід.

Рівень примірника: respond_with

Тут є такі варіанти, які будуть передані для відображення або перенаправлення_ до вашого контролера, але вони включаються лише для сценаріїв успіху. Для GET дій це будуть виклики візуалізації, а для інших дій - це варіанти переадресації. Напевно, найбільш корисним з них є :locationваріант, який можна використовувати для переопрацювання шляху перенаправлення у випадку, якщо аргументів для відповіді_с недостатнім для створення правильної 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'))

В якості альтернативи, відповідачі перлина не тільки пропонують деякі модулі для перевизначення деякого поведінки за замовчуванням. Він переосмислює відповідь за замовчуванням на анонімний клас, який розширює відповідь за замовчуванням, і надає метод рівня класу для змішування в спеціальних модулях до цього класу. Найбільш корисним тут є флеш-реактор, який забезпечує за замовчуванням набір спалахів, делегуючи налаштування за системою I18n, config/locales/en.ymlза замовчуванням.

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


1
Я думаю, ви маєте на увазі (в тілі класу) self.responder =як просто responder =призначений для місцевого
horseyguy

Дякую! Наявність locationваріанту була потрібною мені інформацією!
JellicleCat

1
Це пояснення все ще актуальне для Rails 4/5? Я чув, що respond_withце буде застарілим, але мені не вдається з’ясувати, чому.
Арнлен

1
@Arnlen, response_with був вилучений як окремий дорогоцінний камінь ' responders '
Нік Роз

Зауважте, що для спалахів у вашій config/locales/en.ymlроботі вам потрібно responders :flashу верхній частині контролера.
bjnord
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.