Manejo de JSON en plantilla JS / ERB en Rails 3


No tengo problemas para hacer llamadas AJAX típicas hacia y desde Rails(3) con objetos JSON y jQuery-rails (biblioteca jQuery más un rails especial.archivo js).

En un controlador, sin embargo, quiero devolver algo de JSON en una plantilla erb (create.js.erb) después de una llamada AJAX.

He probado todas las combinaciones de cosas en el controlador (@object.to_json, '[{"content":"hello world"}]', etc.) y en la propia plantilla (JSON.parse (), comillas simples, comillas dobles, etc.), pero el objeto mantiene en la representación de esta manera:

'[{"groups":{},"created_at":"2010-09-21T03:49:34Z" ...

Y como resultado, mi código jQuery no puede analizarlo y obtengo errores.

¿Cómo necesito preparar mi objeto en el controlador y qué sintaxis erb necesito en la vista para que se muestre como un objeto JSON válido?

Muchas Gracias!

Author: Michael Waxman, 2010-09-21

5 answers

No estoy seguro de que esta sea la causa, pero también puedes intentar jugar con el método html_safe. ERB podría estar escapando de su JSON porque cree que no es seguro html. Intente llamar a ese método cuando use la cadena:

@object.to_json.html_safe
 53
Author: alex.zherdev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-09-21 07:14:45

Usando html_escape o rawsolo te dejará vulnerable a XSS.

En su lugar, defina una versión sensible del ayudante json_escape (también conocido como 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

Úsalo así: {[14]]}

<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>

Ver este post para más detalles.

Tenga en cuenta que hay un conflicto de nombres entre j con alias a json_escape en ERB::Util y j con alias a escape_javascript en ActionView::Helpers::JavaScriptHelper. Espero que el alias de JavaScriptHelper cambiar el nombre a js.

 31
Author: John,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-04-30 21:12:15

Para devolver json tienes que escribir tu render en el controlador de la siguiente manera:

render :json => @object

Y el .to_json se llamará automáticamente.

Si quieres incluir algunas relaciones, puedes hacer lo siguiente:

render :json => @post.to_json(:include => [:comments, :authors])

No estoy seguro de si funcionaría usar un erb para renderizar tu json.

 1
Author: nathanvda,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-09-21 09:16:11

Puede llamar a render en su controlador, pero eso será un problema si necesita posiblemente renderizar más de unos pocos parciales para la inserción posterior del dom por el controlador. Necesitaba establecer múltiples fragmentos html en un hash, y he sido capaz de devolver erb que básicamente utiliza hash.to_json.html_safe como neutrino sugiere anteriormente y me permite renderizar múltiples parciales en el proceso.

 0
Author: wkhatch,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-10-20 17:51:25

Solo se necesita to_json.html_safe:

> `'<script>'.to_json`
=> "\"\\u003cscript\\u003e\""

Parche para hacer que to_json responda a html_safe? y devuelva true automáticamente:

# 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
Author: brauliobo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-08-02 17:33:25