11
votes

Les demandes dans les rails ne mettent pas à jour le statut sur les appels de réponse_with

Compte tenu du contrôleur suivant dans les rails:

curl -i --header "Accept: application/json" --header "Content-type: application/json" -X GET http://localhost:3000/api/accounts/3d2cc5d0653911e2aaadc82a14fffee9
HTTP/1.1 404 Not Found 
Content-Type: application/json; charset=utf-8
X-Ua-Compatible: IE=Edge
Cache-Control: no-cache
X-Request-Id: 9cc0d1cdfb27bb86a206cbc38cd75473
X-Runtime: 0.005118
Server: WEBrick/1.3.1 (Ruby/1.9.3/2013-01-15)
Date: Thu, 24 Jan 2013 08:19:45 GMT
Content-Length: 116
Connection: Keep-Alive

{"friendly-status":"not-found","status":404,"message":"No account with id '3d2cc5d0653911e2aaadc82a14fffee9' found"}


6 commentaires

Avez-vous essayé répond_with error_hash, Status: 404, ... au lieu de la représentation du symbole de l'état?


Avez-vous vérifié que votre action #update est-elle appelée? Essayez Soulevez "Test" sur la ligne après DEF update et voyez s'il augmente une erreur.


J'ai essayé ces deux choses. J'ai un logger.debug "Échec de la mise à jour de l'objet avec les params # {param" [: compte} pour ID # {id} "et un répond_with error_hash, état: 404` Mais cela ne semble pas travail.


(Comme dans, la méthode est appelée, mais j'ai le même résultat).


Il est intéressant de noter que cela ne semble être qu'un problème avec réponse_with , il fonctionne simplement bien avec réponse_to . Je me demande si c'est un bug, maintenant.


Je suis d'accord, je pense que ce doit être un bug. Il n'y a aucune bonne raison pour ce comportement que je peux penser. Pour l'instant, je travaille autour d'elle en utilisant rendu au lieu de répond_with mais il se sent sale.


3 Réponses :


3
votes

Avez-vous vu ActionController :: Classe de répondeur? Voici quelques méthodes pour réfléchir à

def api_behavior(error)
      raise error unless resourceful?

      if get?
        display resource
      elsif post?
        display resource, :status => :created, :location => api_location
      else
        head :no_content
      end
    end


0 commentaires

4
votes

Selon Cette discussion Ce comportement plutôt intuitif est due au désir de Maintenir la compatibilité avec l'échafaud.

En général, nous gardons le répondeur la même mise en œuvre que la échafaud. Cela nous permet de dire: remplacer répond_to par réponse_with et tout fonctionnera exactement la même chose.

- Josevalim

Vous avez deux choix pour remplacer le comportement par défaut.

a) passe un bloc à réponse_with xxx

Il est malheureux que nous doivent revenir à la duplication pour chaque format, mais cela semble être la recommandation actuelle jusqu'à Rails 4.0 jusqu'à présent; Voir ici .

Vous devriez revenir 200 - OK , pas 204 - Pas de contenu Si vous retournez l'objet mis à jour ou que vous ne renvoyez rien et que votre code client "obtient" l'objet mis à jour. : L'emplacement n'est pas significatif dans un contexte API, il est de rediriger une réponse HTML.

b) Créer un répondeur personnalisé xxx

je n'ai pas fait Ceci moi-même, je ne peux donc pas donner un exemple, mais cela semble être trop exclu ici de toute façon.

Découvrez Railscasts Episode: 224 Pour une discussion sur la réponse à la réponse, y compris les intervenants personnalisés.


0 commentaires

0
votes

IMHO, je voudrais simplement essayer cela en premier. Le .first! Code> fera des rails émettre un 404 si l'enregistrement n'est pas trouvé. En cas de succès rendu 204. En cas d'erreur lors de l'enregistrement, il extrait des erreurs de l'objet Erreurs du modèle.

class AccountsController < ApplicationController
  respond_to :json, :xml

  def update
    @account = Account.where(uuid: params[:id]).first!
    if @account.update_attributes params[:account]
      respond_with @account, location: account_url(@account)
    else
      respond_to error_hash do |format|
        format.json { render json: error_hash, status: :unprocessable_entity }
        format.xml { render xml: error_hash, status: :unprocessable_entity }
      end
    end
  end

  def error_hash
    { :example => "Example for this question", :parameter => 42 }
  end
end


0 commentaires