2013-02-27 112 views
2

我在升級舊的遺留的過程就是編碼錯誤的Rails 2.3的應用程序,以更現代的東西,並運行到一個編碼問題。我已閱讀了關於此問題的所有現有答案,但仍遇到問題。上的Ruby 1.9.3 Rails的2.3

Rails的版本:2.3.17 紅寶石版本:1.9.3p385

我的MySQL表的默認字符集:utf8,整理:utf8_general_ci。在1.9之前,我正在使用原來的mysql寶石,沒有發生事故。升級到1.9時,檢索與它的UTF8字符什麼會得到這個證據充分的問題後:

ActionView::TemplateError (incompatible character encodings: ASCII-8BIT and UTF-8) 

我切換到mysql2寶石爲它的優越的操控,我再也看不到異常,但事情肯定不是編碼正確。例如,什麼樣的數據庫顯示爲字符串Repoussé是由Rails的渲染爲Repoussé「Boat」出現“Boatâ€

的詳細原因:

  • 我看到了相同的結果,當我使用作爲驅動程序的寶石ruby-mysql
  • 我添加encoding: utf8線,每個條目在我database.yml

我還添加以下到我的environment.rb

Encoding.default_external = Encoding::UTF_8 
Encoding.default_internal = Encoding::UTF_8 

它發生,我認爲我可能有一些不匹配latin1正在被舊版本的應用程序寫入數據庫的utf8字段中,但在mysql命令行客戶端中查看時,所有字符均正確顯示。

預先感謝任何建議,非常感謝!

更新:我現在認爲,問題是,我的UTF8數據通過二進制轉換脅迫的方式處理latin1出來的分貝,我只是不知道在哪裏。

mysql> SELECT CONVERT(CONVERT(name USING BINARY) USING latin1) AS latin1, CONVERT(CONVERT(name USING BINARY) USING utf8) AS utf8 FROM items WHERE id=myid; 
+-------------+----------+ 
| latin1  | utf8  | 
+-------------+----------+ 
| Repoussé | Repoussé | 
+-------------+----------+ 

我有我的encoding設置爲在database.yml中utf8,任何其他的想法,其中這可以是從哪裏來的?

+0

只是出於好奇,什麼是你的HTML頁面編碼?它是否明確設置爲「utf-8」? – mudasobwa 2013-02-27 04:22:21

+0

好的想法,是的它是:'' – 2013-02-27 04:32:10

+0

爲了更準確地找到問題來源,我建議你' Logger.debug'從你的模板,模型,無論你的數據。我想,這不是一個破壞數據的'''驅動程序。 – mudasobwa 2013-02-27 04:52:45

回答

6

我終於搞清楚我的問題是什麼。雖然我的數據庫用utf8編碼,與原mysql寶石的應用程序是注射latin1文成utf8表。

什麼扔我是從mysql COMAND行客戶端的輸出看上去是正確的。驗證您的終端,MySQL客戶端的數據庫字段都在utf8中運行是非常重要的。

默認情況下,MySQL的客戶端運行在latin1。你可以發現它是通過發出此查詢運行:

show variables like 'char%'; 

如果設置正確的utf8你應該看到:

+--------------------------+----------------------------+ 
| Variable_name   | Value      | 
+--------------------------+----------------------------+ 
| character_set_client  | utf8      | 
| character_set_connection | utf8      | 
| character_set_database | utf8      | 
| character_set_filesystem | binary      | 
| character_set_results | utf8      | 
| character_set_server  | utf8      | 
| character_set_system  | utf8      | 
| character_sets_dir  | /usr/share/mysql/charsets/ | 
+--------------------------+----------------------------+ 

如果這些看起來不正確,請確保設置以下在my.cnf配置文件的[client]部分:

​​

添加添加以下到[mysqld]部分:

# use utf8 by default 
character-set-server=utf8 
collation-server=utf8_general_ci 

確保重新推出客戶端之前重新啓動mysql的守護進程,然後驗證。

注意:這不會更改現有數據庫的字符集或整理,只是確保創建的任何新數據庫都將默認爲utf8,並且客戶端將顯示在utf8中。

當我這樣做後,我看到在mysql客戶端的字符匹配我從mysql2寶石。我還能夠通過在我的database.conf中暫時切換爲「encoding: latin1」來驗證此內容是否爲latin1

一個非常方便的查詢來發現問題是使用焦炭長度找到與多字節字符的行:

SELECT id, name FROM items WHERE LENGTH(name) != CHAR_LENGTH(name); 

有很多劇本在那裏,以latin1內容轉換爲utf8,但什麼工作最適合我的是傾倒所有數據庫爲latin1的操作,並且將utf8餡的內容背:

mysqldump -u root -p --opt --default-character-set=latin1 --skip-set-charset DBNAME > DBNAME.sql 

mysql -u root -p --default-character-set=utf8 DBNAME < DBNAME.sql 

我支持我的主數據庫,然後再倒入一個測試數據庫和VERI在滾動到更正的數據庫之前瘋狂地瘋狂。

我的理解是,MySQL的轉換可以留下一些東西與某些更復雜的角色期望,但因爲我的大多數多字節字符是相當普遍的事情(重音符號,報價等),這對我來說真是棒極了。

有些資源被證明在所有這一切整理出來的寶貴:

1

你說這一切看起來OK在命令行客戶端,但也許您的終端的字符編碼沒有設置爲顯示UTF8?要檢入OS X Terminal,請單擊終端>首選項>設置>高級>字符編碼。另外,請使用圖形工具(如MySQL查詢瀏覽器)在http://dev.mysql.com/downloads/gui-tools/5.0.html處進行檢查。

+0

感謝您的建議!我的終端編碼設置爲UTF8。 – 2013-02-27 04:29:50