开发者

Rails3 CSV putting "" instead of actual quotes

开发者 https://www.devze.com 2023-04-03 21:44 出处:网络
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:

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.gener开发者_如何学Pythonate 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?


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.


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消