Обработка JSON в шаблоне JS / ERB в Rails 3 - PullRequest
32 голосов
/ 21 сентября 2010

У меня нет проблем с выполнением типичных вызовов AJAX в Rails (3) с объектами JSON и jQuery-rails (библиотека jQuery и специальный файл rails.js).

Однако в одном контроллере я хочу вернуть JSON в шаблоне erb (create.js.erb) после вызова AJAX.

Я пробовал все комбинации в контроллере (@ object.to_json, '[{"content": "hello world"}]' и т. Д.) И в самом шаблоне (JSON.parse (), одинарные кавычки, двойные кавычки и т. д.), но объект продолжает отображаться так:

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

и в результате мой код jQuery не может его проанализировать, и я получаю ошибки.

Как мне нужно подготовить мой объект в контроллере и какой синтаксис erb мне нужен в представлении, чтобы он отображался как действительный объект JSON?

Большое спасибо!

Ответы [ 5 ]

54 голосов
/ 21 сентября 2010

Я не уверен, что это причина, но вы также можете попробовать поиграть с методом html_safe. ERB, возможно, избегает вашего JSON, потому что считает, что это не безопасно в формате HTML. Попробуйте вызвать этот метод при использовании строки:

@object.to_json.html_safe
32 голосов
/ 01 мая 2012

Использование только html_escape или raw сделает вас уязвимым для XSS .

Вместо этого определите разумную версию помощника json_escape (он же 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

Используйте это так:

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

См. этот пост для получения дополнительной информации.

Имейте в виду, что есть конфликт имен между j с псевдонимом json_escape в ERB :: Util и j с псевдонимом escape_javascript в ActionView :: Helpers :: JavaScriptHelper.Я надеюсь, что псевдоним JavaScriptHelper будет переименован в js.

1 голос
/ 21 сентября 2010

Для возврата json вы должны записать свой рендер в контроллере следующим образом:

render :json => @object

и .to_json будет вызван автоматически.

Если вы хотите включить некоторые отношения, вы можете сделать следующее:

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

Я не уверен, сработает ли использование erb для рендеринга вашего json.

0 голосов
/ 02 августа 2015

Только to_json.html_safe необходимо:

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

Патч, чтобы to_json отвечал на html_safe? и возвращал true автоматически:

# 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 голосов
/ 20 октября 2010

Вы можете вызвать render в вашем контроллере, но это будет проблемой, если вам понадобится отрендерить несколько партиалов для последующей вставки dom обработчиком. Мне нужно было установить несколько html-фрагментов в хеш, и я смог вернуть erb, который в основном использует hash.to_json.html_safe, как предполагает выше нейтрино, и позволяет мне визуализировать несколько частичек в процессе.

...