Nicolas Raoul
Nicolas Raoul

Reputation: 60213

Displaying UTF-8 in ERB says "incompatible character encodings" (no database involved)

In my ERB page, I want to display one of the country names configured in this CSV file:

Suisse
Deutschland
日本

Here is the code that loads the CSV in config/initializers:

require 'csv'
COUNTRIES = CSV.read("#{RAILS_ROOT}/config/countries.csv").flatten

Here is the code in the ERB:

<%= "Country:" + COUNTRIES[id].to_s %>

I displays fine when id=0 or id=1, but when id=2 an error appears:

incompatible character encodings: ASCII-8BIT and UTF-8

...with the error pointing to the ERB line above.
How to fix it?

No database involved, Ruby 1.9.2-p180. UTF-8 from localization files is displayed fine.

Upvotes: 1

Views: 1945

Answers (2)

emboss
emboss

Reputation: 39630

From CSV#read docs:

This method also understands an additional :encoding parameter that you can use to specify the Encoding of the data in the file to be read. You must provide this unless your data is in Encoding::default_external(). CSV will use this to deterime how to parse the data.

So just to be safe, I would first use

COUNTRIES = CSV.read("/Users/dumitru/test.csv", { encoding: "UTF-8" }).flatten

and check what

COUNTRIES[2].encoding.name

says a) directly after CSV#read and b) when executed in your ERB template. If it says "US-ASCII" there then you should check whether something accidentally changes your COUNTRIES after parsing them. At least you can then be sure that something's odd inbetween.

I would also prefer

<%= "Country:" + COUNTRIES[id] %>

since you already have strings there. But I don't think this will cure the issue, though.

I couldn't imagine that something actually changed the contents of the string but maybe the encoding got reassociated as US-ASCII. So you might have a good chance to use

COUNTRIES[2].force_encoding("UTF-8")

with your string in order to enforce the association back to UTF-8. If that doesn't help I'd try

COUNTRIES[2].encode("UTF-8")

If all of these methods fail, I would need to know the encoding at the time you try to render the string in your ERB template to help you further.

Upvotes: 5

Dumitru Ceban
Dumitru Ceban

Reputation: 640

seems that your csv file isn't saved in UTF-8, try to convert it to utf-8

edit: I've tested the above example on my local mac, using the same ruby version and it works without issues. I've created a csv from scratch and tested on irb.

ruby-1.9.2-p180 :004 > require 'csv'
=> true  
ruby-1.9.2-p180 :006 > COUNTRIES = CSV.read("/Users/dumitru/test.csv").flatten
=> ["Suisse", "Deutschland", "\xE6\x97\xA5\xE6\x9C\xAC"] 
ruby-1.9.2-p180 :007 > "Country:" + COUNTRIES[0].to_s
=> "Country:Suisse" 
ruby-1.9.2-p180 :009 > "Country:" + COUNTRIES[2].to_s
=> "Country:\xE6\x97\xA5\xE6\x9C\xAC" 

Upvotes: 0

Related Questions