Rails respond_with: comment ça marche?

J’ai lu ici et là à propos de la façon dont la méthode respond_with est cool dans Rails 3. Mais je ne peux même pas trouver de référence dans les API Rails ou en recherchant la source. Est-ce que n’importe qui peut m’expliquer comment cela fonctionne (quelles options vous pouvez utiliser, etc.) ou me diriger vers l’endroit où il est réellement implémenté afin que je puisse lire le code tout seul?

Mise à jour pour Rails 4.2+

#respond_with ::respond_to classe nb et ::respond_to ne font plus partie de Rails . Ils ont été migrés dans la pierre précieuse des répondeurs tiers à partir de Rails 4.2 ( notes de version / commit datée d’août 2014). Bien que les répondeurs ne soient pas inclus dans Rails par défaut, il s’agit d’une dépendance de Devise, et donc disponible dans de nombreuses applications Rails.

La méthode d’instance #respond_to , cependant, fait toujours partie de Rails (5.2rc1 à ce jour).

La documentation officielle de l’API Rails pour ActionController::MimeResponds explique comment #respond_to fonctionne. Les commentaires de la documentation d’origine sur les guides Rails pour #respond_with et ::respond_to peuvent toujours être trouvés dans le code source du répondeur .


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, les seuls rails de comportement fournis dans la réponse sont une tentative implicite de rendu d’un modèle avec un nom correspondant à l’action. Tout ce qui dépasse requirejs plus d’instructions dans l’action, ou un appel personnalisé respond_to avec un bloc pour gérer plusieurs réponses au format.

Comme la plupart des contrôleurs utilisent un modèle de personnalisation assez commun, les répondeurs fournissent un niveau d’abstraction supplémentaire en introduisant davantage de comportements par défaut. Actions de lecture appelant to_xml / to_json pour des formats spécifiques, et actions de mutateur fournissant les mêmes ainsi que des redirections pour des actions de mutateur réussies.


Il existe quelques possibilités de personnaliser le comportement des répondeurs, des modifications subtiles à la modification complète ou à l’extension du comportement.

Niveau de la classe: respond_to

Vous spécifiez ici les formats que le répondeur doit gérer. Les formats peuvent être personnalisés en fonction des actions auxquelles ils s’appliqueront. 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 la classe: responder

Ceci est un atsortingbut de classe qui contient le répondeur. Cela peut être tout ce qui répond à l’appel, ce qui signifie que vous pouvez utiliser un proc / lambda ou une classe qui répond à l’appel. Une autre alternative consiste à combiner un ou des 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, il est plus probable que l’extension ou le mixage des modules dans le répondeur par défaut soit plus courant. Dans tous les cas, les options pertinentes sont les ressources et les options, car elles sont transmises par from 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 pour les scénarios de réussite. Pour les actions GET, il s’agirait des appels de rendu, pour les autres actions, ce sont les options de redirection. Le plus utile d’entre eux est probablement l’option :location , qui peut être utilisée pour remplacer ce chemin de redirection si les arguments de respond_with ne sont pas suffisants pour créer 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 ssortingng # then the location option would be needed. # /users?scope=active respond_with(@user, :location => users_path(:scope => 'active')) 

En guise d’alternative, le joyau des répondeurs ne fournit pas seulement des modules pour remplacer certains comportements par défaut. Il remplace le répondeur par défaut par une classe anonyme qui étend le répondeur par défaut et fournit une méthode de niveau de classe pour 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 utilisés dans des projets précédents, citons un répondeur qui a automatiquement décoré mes ressources et fourni un jeu de titres de page par défaut avec une interface permettant de personnaliser ou de remplacer facilement le titre de la page.