web-dev-qa-db-fra.com

Rails respond_with: comment ça marche?

Je lisais ça et là à propos de la fraîcheur du respond_with La méthode est in Rails 3.). Mais je ne peux même pas trouver de référence dans les API Rails ni en recherchant la source. Quelqu'un peut-il ou expliquez-moi comment cela fonctionne (quelles options vous pouvez utiliser, etc.) ou dirigez-moi vers l'endroit où il est réellement implémenté afin que je puisse parcourir le code moi-même?

121
jaydel

Mise à jour pour Rails 4.2+

#respond_with et ::respond_to ( n.b. la méthode de classe) ne fait plus partie de Rails . Ils ont été migrés vers les tiers répondeurs , gem, à partir de Rails 4.2 ( ) notes de publication / commit du mois d’août 2014. Bien que les répondants ne soient pas inclus dans Rails par défaut, il s’agit d’une dépendance de Devise et est donc disponible dans de nombreuses versions. Rails applications.

Le #respond_to méthode d'instance, Toutefois, fait toujours partie de Rails (5.2rc1 à la date de cette écriture).

L’officiel Rails de l’API pour ActionController::MimeResponds explique comment #respond_to travaux. L'original Rails Commentaires de la documentation de guides pour #respond_with et ::respond_to se trouve toujours dans le code source des répondeurs .


Réponse originale

Le code pour les répondeurs est basé sur une classe et un module. MimeResponds qui est inclus dans ActionController :: Base , la classe dont votre ApplicationController hérite. Ensuite, il y a ActionController :: Responder qui fournit le comportement par défaut lors de l'utilisation de respond_with.


Par défaut, le seul comportement Rails fournit dans la réponse est une tentative implicite de restitution d'un modèle dont le nom correspond à l'action. Tout ce qui est au-delà nécessite davantage d'instructions dans l'action, ou un appel personnalisé à respond_to avec un bloc pour gérer les réponses de plusieurs formats.

Comme la plupart des contrôleurs utilisent un schéma de personnalisation assez commun, les répondeurs fournissent un niveau supplémentaire d'abstraction en introduisant davantage de comportements par défaut. Lisez les actions appelant to_xml/to_json pour des formats spécifiques et les actions de mutateur fournissant la même chose, ainsi que des redirections pour les actions de mutateur réussies.


Il existe quelques possibilités pour personnaliser le comportement des intervenants, allant d'ajustements subtils à l'annulation ou l'extension complète du comportement.

Niveau de classe: respond_to

Ici, vous spécifiez les formats que le répondeur doit gérer. Les formats peuvent être personnalisés en fonction des actions à appliquer. Chaque format peut être spécifié avec des appels séparés, permettant une personnalisation complète des actions pour chaque format.

# 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]

Niveau de classe: responder

C'est un attribut de classe qui contient le répondeur. Cela peut être n'importe quoi qui répond à un appel, ce qui signifie que vous pouvez utiliser un proc/lambda ou une classe qui répond à un appel. Une autre solution consiste à mélanger un ou plusieurs modules au répondeur existant pour surcharger les méthodes existantes, en augmentant le comportement par défaut.

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

Bien qu'il puisse y avoir des cas d'utilisation intéressants dans Edge, il est plus probable que l'extension ou le mélange de modules dans le répondeur par défaut soient des modèles plus courants. Dans tous les cas, les options pertinentes sont les ressources et les options, telles qu'elles sont transmises depuis le paramètre respond_with.

Niveau d'instance: respond_with

Les options ici sont celles qui seraient transmises à render ou redirect_to dans votre contrôleur, mais elles ne sont incluses que dans les scénarios de réussite. Pour les actions GET, ce sont les appels de rendu, pour les autres actions, ce sont les options de redirection. Le plus utile d'entre eux est probablement le :location option, qui peut être utilisée pour remplacer ce chemin de redirection au cas où les arguments de respond_with ne seraient pas suffisants pour construire la bonne 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'))

En guise d'alternative, le répondeur fournit non seulement des modules permettant de redéfinir certains comportements par défaut. Il substitue au répondeur par défaut une classe anonyme qui étend le répondeur par défaut et fournit une méthode au niveau de la classe permettant de mélanger des modules personnalisés à cette classe. Le plus utile ici est le répondeur flash, qui fournit un ensemble de flashs par défaut, déléguant la personnalisation au système I18n, config/locales/en.yml par défaut.

Parmi les exemples de répondeurs personnalisés que j'ai utilisés dans des projets précédents, citons un répondeur qui décorait automatiquement mes ressources et fournissait un ensemble par défaut de titres de page avec une interface permettant de personnaliser ou de remplacer facilement le titre de la page.

123
Cluster