130 votes

Dans Rails, comment rendre JSON à l'aide d'une vue ?

Supposons que vous êtes dans votre contrôleur users et que vous voulez obtenir une réponse json pour une requête show, ce serait bien si vous pouviez créer un fichier dans votre répertoire views/users/, nommé show.json et après que votre action users#show soit terminée, il rend le fichier.

Actuellement, vous devez faire quelque chose du genre :

def show
  @user = User.find( params[:id] )
  respond_to do |format|
    format.html
    format.json{
      render :json => @user.to_json
    }
  end
end

Mais ce serait bien si vous pouviez créer un fichier show.json qui serait automatiquement rendu comme ceci :

def show
  @user = User.find( params[:id] )
  respond_to do |format|
    format.html
    format.json
  end
end

Cela m'épargnerait des tonnes de soucis, et effacerait cette horrible sensation de saleté que je ressens lorsque je rends mon json dans le contrôleur.

0 votes

En regardant ce post maintenant, il semble que cela ne me sauverait pas beaucoup, mais j'ai des cas plus compliqués, croyez-moi quand je dis que cela me donne des maux de tête.

1 votes

Dans Rails 3, vous pouvez simplement appeler format.json con un show.json.erb fichier. Voir ma réponse.

66voto

Alex Reisner Points 10026

Vous devriez être en mesure de faire quelque chose comme cela dans votre respond_to bloc :

respond_to do |format|
    format.json 
    render :partial => "users/show.json"
end

qui rendra le modèle dans app/views/users/_show.json.erb .

6 votes

C'est bien, mais vous découvrirez rapidement que erb est un moyen pénible de générer du json. Consultez ma réponse pour trouver des alternatives.

1 votes

Y a-t-il un moyen de le faire sans utiliser un partiel ?

58voto

erik Points 3923

Essayez d'ajouter une vue users/show.json.erb Il devrait être rendu lorsque vous faites une demande pour le format JSON, et vous obtenez l'avantage supplémentaire d'être rendu par erb aussi, donc votre fichier pourrait ressembler à quelque chose comme ceci

{
    "first_name": "<%= @user.first_name.to_json %>",
    "last_name": "<%= @user.last_name.to_json %>"
}

9 votes

Vous pouvez utiliser @user.first_name.to_json au lieu de escape_javascript . Il y a quelques différences subtiles entre ce que JS permet et ce qui est strictement JSON. (Et ces différences deviennent importantes à mesure que les navigateurs mettent en œuvre leurs propres analyseurs JSON).

1 votes

Vous devriez probablement remplacer les guillemets simples par des guillemets doubles, car JSON (contrairement à JS) n'accepte que les chaînes entre guillemets doubles.

1 votes

C'est bien, mais vous découvrirez rapidement qu'erb est un moyen pénible de générer du json. Consultez ma réponse pour trouver des alternatives.

33voto

tybro0103 Points 13198

Comme d'autres l'ont mentionné, vous avez besoin d'une vue users/show.json, mais il y a des options à considérer pour le langage de templating...

ERB

Fonctionne dès la sortie de la boîte. Excellent pour le HTML, mais vous vous rendrez vite compte qu'il est horrible pour le JSON.

RABL

Bonne solution. Il faut ajouter une dépendance et apprendre sa DSL.

Constructeur JSON

Même chose que RABL : bonne solution. Il faut ajouter une dépendance et apprendre son DSL.

Plain Ruby

Ruby est excellent pour générer du JSON et il n'y a rien de nouveau à apprendre puisque vous pouvez appeler to_json sur un hachoir ou un objet AR. Il suffit d'enregistrer l'extension .rb pour les modèles (dans un initialisateur) :

ActionView::Template.register_template_handler(:rb, :source.to_proc)

Puis créez la vue users/show.json.rb :

@user.to_json

Pour plus d'informations sur cette approche, voir http://railscasts.com/episodes/379-template-handlers

10 votes

Notez que dans rails 4, le gestionnaire de modèle .ruby est enregistré par défaut. github.com/rails/rails/commit/de1060f4e02925c12004f2 donc vous pouvez sauter l'enregistrement de .rb et nommer votre fichier users/show.json.ruby.

1 votes

De plus, pour mettre à jour ce point, json_builder a été remplacé par github.com/rails/jbuilder .

27voto

zapnap Points 232

RABL est probablement la solution la plus agréable que j'ai vue à ce sujet si vous cherchez une alternative plus propre à la syntaxe ERb. json_builder et argonaut, qui sont d'autres solutions, semblent tous deux quelque peu dépassés et ne fonctionneront pas avec Rails 3.1 sans un certain Parcheando.

RABL est disponible via une gemme ou consultez le dépôt GitHub ; de bons exemples aussi

https://github.com/nesquena/rabl

21voto

Jim Lim Points 4981

Je tiens à mettre à jour cette réponse pour le bien des autres personnes qui se retrouveraient sur cette page.

Dans Rails 3, il suffit de créer un fichier à l'adresse views/users/show.json.erb . Le site @user sera disponible pour la vue (comme il le serait pour le html). to_json plus.

Pour résumer, c'est juste

# users contoller
def show
  @user = User.find( params[:id] )
  respond_to do |format|
    format.html
    format.json
  end
end

y

/* views/users/show.json.erb */
{
    "name" : "<%= @user.name %>"
}

2 votes

J'ai répondu à cette question il y a un an et demi. Aujourd'hui, j'utilise simplement respond_with lorsque j'ai besoin de JSON, par exemple. respond_with @user, only: [:name] . Se référer à ce tutoriel pour plus d'informations.

1 votes

Pour compléter cette réponse, cette méthode est en fait dangereuse pour deux raisons : elle permet l'injection de données utilisateur parce qu'elle n'échappe pas les nouvelles lignes et les antislashs, et aussi <%= html échappe les données, donc par exemple Sean O'Connor verra son nom transformé en Sean O'Connor.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X