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!
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
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 raw
solo 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
.
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.
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.
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
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