risentveber
@risentveber
fullstack web developer

Как правильно в Rails преобразовывать HTML в строку для JSON объекта?

Есть вьюха, которая предназначена для ответа JSONом на
AJAX запрос:
{
  "description": "<%=  @homework.description %>",
  "form_link": "<%= classroom_homework_path(classroom_id, @homework) %>",
  "attachment_ids":  "<%= @homework.attachments.ids.join " " %>",
  "html_id" : "homework<%= @homework.id %>"
  <% if @homework.subject_id %>
    ,"tag": <%= @homework.subject_id %>
  <% end %>
  ,"files": [
    <% first = true %>
    <% @homework.attachments.each do |f| %>

      <% if first %>
        <% first = false %>
      <% else %>
        ,
      <% end %>
      "<%= (render partial: "materials/file", object: f, formats: :html).to_json %>"
    <% end %>
  ]

}

Соответствующий partial:
<div class="this-material this-material-preview show-X">
  <div class = 'del-this-file'>
    <a class = 'X18' attachment = '<%= file.id%>'>×</a>
  </div>
  <div class="files-image type-document">
  </div>
  <div class="name-files">
    <%= link_to truncate(file.file.file.filename, length: 30), file.file.url %>
  </div>
</div>

Данный код создает не валидный JSON в области рендеринга HTML - проблема с двойными кавычками и переносом строк.
Как вообще правильно решать задачу рендеринга HTML в JSON объект с помощью Rails?
  • Вопрос задан
  • 368 просмотров
Решения вопроса 1
mainameiz
@mainameiz
Full-stack web-developer
Вам нужен jbuilder (DSL для генерации json'а) или active_model_serializers (реализует объектный подход к генерации json'а)
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
viktorvsk
@viktorvsk
Очень сложно что-то разобрать, конечно. А что должно находиться в ключе files, мой мозг, лично, за 2 минуты скомпилировать не смог.

Разбейте "рефакторинг", если это можно так назвать, на такие шаги:
1. Забейте на HTML партиал
2. Вместо того, что б собирать текстовый JSON вручную во вьюхе, соберите руби-хэш в контроллере и вызовите на нем to_json. Например:
def my_action
  res = {
    description: @homework.description,
    ...
    html_id: "homework#{@homework.id}"
  }
  res[:tag] = @homework.subject_id if @homework.subject_id
end

3. Добейтесь, что б res.to_json выдавал необходимый результат.
4-а. Почитайте про each_with_index
4-б. Почитайте про Rails Rendering Collections, пункт 3.4.5
4. Допишите и добейтесь, что б работало:
res[:files] = render @homework.attachments
5. В идеале, засуньте это все в модель. Например, переопределите для Homework метод to_json. Отличие будет только в том, что render нужно будет вызывать как-то типа ActionController::Base.new.render(...)
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы