Rails3 CSV putting "" instead of actual

2019-06-28 01:02发布

Similar to this question except I don't use html_safe anywhere in the whole project.

I generate a CSV file in index.csv.erb like this:

<%=
response.content_type = 'application/octet-stream'
CSV.generate do |csv|
  @persons.each do |person|
    csv << [ person[:name], person[:nickname] ]
  end
end
%>

PROBLEM: If nickname is NULL in the database (ActiveRecord/MySQL) then the CSV file associated element becomes &quot;&quot;. I would expect "", or even nothing at all.

Result file sample:

Nicolas, Nico
Joe, &quot;&quot;

How can I prevent this from happening?

2条回答
我只想做你的唯一
2楼-- · 2019-06-28 01:45

The problem here is that you're not using html_safe. Your nickname field is blank and converted to "" in the csv file, but it is deemed unsafe by Rails and html escaped.

Just call html_safe on the result:

<%=
response.content_type = 'application/octet-stream'
CSV.generate do |csv|
  @persons.each do |person|
    csv << [ person[:name], person[:nickname] ]
  end
end .html_safe
%>

The solution you linked to does not work anymore with Rails 3 because all strings are considered unsafe by default, which was not the case in Rails 2.

查看更多
贼婆χ
3楼-- · 2019-06-28 01:56

Refactored

Benoit is absolutely correct and thanks for that tip. After looking at your code I see a much cleaner approach to generating your CSV as well, which I thought I would share for those landing here (like me!):

<%=
response.content_type = 'application/octet-stream'
@persons.collect{ |person| [ person[:name], person[:nickname] ].to_csv }.join.html_safe 
%>

Essentially, you don't need all that CSV generate stuff. Ruby can take an Array and turn it into a CSV string, then just use a collect and join to put it all together nicely.

You can also do the following if you prefer having it on separate lines, which I do:

<% response.content_type = 'application/octet-stream' -%> 
<% @persons.each do |person| -%>
  <%= [ person[:name], person[:nickname] ].to_csv( row_sep: nil ).html_safe %>
<% end -%>

Here you'll need to use the -%> to ensure you don't get extra blank lines and you'll need to use the row_sep: nil option so that to_csv doesn't add a \n at the end of each line.

Anyway, hope that helps clean some people's code up.

查看更多
登录 后发表回答