R
R
Risent Veber2015-07-11 13:42:41
JavaScript
Risent Veber, 2015-07-11 13:42:41

What is the correct way to convert HTML to a string for a JSON object in Rails?

There is a view that is designed to respond with JSON to an
AJAX request:

{
  "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 %>
  ]

}

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

This code produces invalid JSON in the HTML render area - double quotes and line wrapping issue.
What is the correct way to solve the problem of rendering HTML to JSON object using Rails?

Answer the question

In order to leave comments, you need to log in

2 answer(s)
N
Nikolai Markov, 2015-07-11
@risentveber

You need jbuilder (DSL for json generation) or active_model_serializers (implements object approach to json generation)

V
Viktor Vsk, 2015-07-11
@viktorvsk

It is very difficult to parse something, of course. And what should be in the files key, my brain, personally, could not compile in 2 minutes.
Break down the "refactoring", if you can call it that, into the following steps:
1. Throw in the HTML partial
2. Instead of manually collecting text JSON in the view, collect the ruby ​​hash in the controller and call to_json. For example:

def my_action
  res = {
    description: @homework.description,
    ...
    html_id: "homework#{@homework.id}"
  }
  res[:tag] = @homework.subject_id if @homework.subject_id
end

3. Get what res.to_jsonwould give the desired result.
4-a. Read about each_with_index
4-b. Read about Rails Rendering Collections, paragraph 3.4.5
4. Add and make it work:
5. Ideally, shove it all into the model. For example, override Homework's to_json method. The only difference will be that render will need to be called somehow likeActionController::Base.new.render(...)

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question