Gestion de JSON dans le modèle JS / ERB dans Rails 3
Je n'ai aucun mal à faire des appels AJAX typiques vers et depuis Rails (3) avec des objets JSON et des rails jQuery (bibliothèque jQuery plus un rail spécial.fichier js).
Dans un contrôleur, cependant, je veux retourner un JSON dans un modèle erb (create.js.erb) après un appel AJAX.
J'ai essayé toutes les combinaisons de choses dans le contrôleur (@objet.to_json, '[{"contenu":"hello world"}]', etc.) et dans le modèle lui-même (JSON.parse (), guillemets simples, guillemets doubles, etc.), mais l'objet garde sur le rendu comme ceci:
'[{"groups":{},"created_at":"2010-09-21T03:49:34Z" ...
Et par conséquent, mon code jQuery ne peut pas l'analyser et j'obtiens des erreurs.
Comment dois-je préparer mon objet dans le contrôleur, et de quelle syntaxe erb ai-je besoin dans la vue pour qu'il soit rendu en tant qu'objet JSON valide?
Merci beaucoup!
5 réponses
Je ne suis pas sûr que ce soit la cause, mais vous pouvez également essayer de jouer avec la méthode html_safe
. ERB pourrait échapper à votre JSON car il pense que ce n'est pas html sûr. Essayez d'appeler cette méthode Lorsque vous utilisez la chaîne:
@object.to_json.html_safe
Utiliser html_escape
ou raw
seul vous laissera vulnérables aux attaques de type XSS.
Au lieu de cela, définissez une version sensible de l'Assistant json_escape
(alias j
):
module ActionView::Base
def json_escape(s)
result = s.to_s.gsub('/', '\/')
s.html_safe? ? result.html_safe : result
end
alias j json_escape
end
Utilisez-le comme ceci:
<script>
var Accounts = new Backbone.Collection;
Accounts.reset(<%=j @accounts.to_json.html_safe %>);
var Projects = new Backbone.Collection;
Projects.reset(<%=j @projects.to_json(:collaborators => true).html_safe %>);
</script>
Voir ce post pour plus de détails.
Être conscient qu'il y a un conflit de noms entre j
alias json_escape
dans ERB::Util et j
alias escape_javascript
dans ActionView::Assistants::JavaScriptHelper. C'est mon espoir que L'alias JavaScriptHelper sera être renommé en js
.
Pour revenir json
vous devez écrire votre rendu dans le contrôleur comme suit:
render :json => @object
Et le .to_json
sera automatiquement appelé.
Si vous souhaitez inclure certaines relations, vous pouvez faire ce qui suit:
render :json => @post.to_json(:include => [:comments, :authors])
Je ne suis pas sûr si cela fonctionnerait d'utiliser un erb pour rendre votre json.
Vous pouvez appeler render dans votre contrôleur, mais ce sera un problème si vous avez besoin de rendre plus de quelques partiels pour une insertion dom ultérieure par le gestionnaire. J'avais besoin de définir plusieurs fragments html dans un hachage, et j'ai pu retourner erb qui utilise essentiellement hash.to_json.html_safe comme neutrino le suggère ci-dessus et me permet de rendre plusieurs partiels dans le processus.
Seulement to_json.html_safe
est nécessaire:
> `'<script>'.to_json`
=> "\"\\u003cscript\\u003e\""
Patch pour que to_json
réponde à html_safe?
et retourne true
automatiquement:
# just use .to_json instead of .to_json.html_safe
ActiveSupport::JSON.class_eval do
class << self
def encode_with_html_safe *args
self.encode_without_html_safe(*args).html_safe
end
alias_method_chain :encode, :html_safe
end
end