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!

31
demandé sur Michael Waxman 2010-09-21 09:10:40

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
53
répondu alex.zherdev 2010-09-21 07:14:45

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.

31
répondu John 2012-04-30 21:12:15

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.

1
répondu nathanvda 2010-09-21 09:16:11

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.

0
répondu wkhatch 2010-10-20 17:51:25

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
0
répondu brauliobo 2015-08-02 17:33:25