Ruby on Rails CSV put "" вместо фактических котировок

Я пытаюсь создать файл CSV. Все отлично, за исключением пустых полей, я не уверен, что "" вместо фактических котировок. Я предоставил код, который я использую, чтобы сгенерировать файл и некоторый вывод.

<% headers = ["Username", "Name", "E-mail", "Phone Number"] %>
<%= CSV.generate_line headers %>

<% @users_before_paginate.each do |user| %>
  <% row = [ "#{user.username}".html_safe ] %>
  <% row << "#{user.profile.first_name} #{user.profile.last_name}".html_safe unless user.profile.blank? %>
  <% row << "#{user.email}".html_safe unless user.profile.nil? %>
  <% row << "#{user.profile.phone}".html_safe unless user.profile.nil? %>
  <%= CSV.generate_line row %>
<% end %>

Выход

Username,Name,E-mail,Phone Number

  admin,LocalShopper ,[email protected],&quot;&quot;
  Brian,Oliveri Design ,[email protected],727-537-9617
  LocalShopperJenn,Jennifer M Gentile ,[email protected],&quot;&quot;

Ответ 1

Вместо того, чтобы вызывать html_safe в каждой части массива и затем создавать из него новую (не-html-безопасную) строку, попробуйте вызвать ее в конце, после того, как строка будет возвращена из generate_line:

<%= CSV.generate_line(row).html_safe %>

ОБНОВЛЕНИЕ:. Для обеспечения безопасности вы должны быть уверены, что этот шаблон не отправляется в браузер как HTML, но исходный текст /csv . Если содержимое строки содержит любые фактические теги HTML, такие как <script>, они не будут экранированы, потому что вы объявили вывод "безопасным".

Если это содержимое должно выводиться на странице HTML, вам лучше рассмотреть правильное экранирование, а не обходить его так.

Рассмотрим, действительно ли вам нужен шаблон html.erb для генерации CSV.

Ответ 2

Вот шаблон, который я использовал, который работает достаточно хорошо:

<%=
  response.content_type = 'application/octet-stream'

  FasterCSV.generate do |csv|
    csv << @report[:columns]
    @report[:rows].each do |row|
      csv << row
    end
  end
%>

Вы можете сделать это полностью в контроллере, если хотите, и сделать его как тип :text.

Это также помогает, если вы нарушаете содержимое на заказ, в данном случае простой хеш @report внутри контроллера, чем для выполнения всего тяжелого подъема в представлении.