Problemas de MySQL UTF8 en Rails – problemas de encoding con utf8_general_ci

Tengo un sitio provisional de Rails que se ejecuta en MySQL 5.0.32-Debian.

En este sitio en particular, todas mis tablas usan la encoding utf8 / utf8_general_ci .

Dentro de esa base de datos, tengo algunos datos que se ven así:

 mysql> select * from currency_types limit 1,10; +------+-----------------+---------+ | code | name | symbol | +------+-----------------+---------+ | CAD | Canadian Dollar | $ | | CNY | Chinese Yuan | 元 | | EUR | Euro | € | | GBP | Pound | £ | | INR | Indian Rupees | ₨ | | JPY | Yen | ¥ | | MXN | Mexican Peso | $ | | USD | US Dollar | $ | | PHP | Philippine Peso | ₱ | | DKK | Denmark Kroner | kr | +------+-----------------+---------+ 

Aquí está el problema que estoy teniendo

En la preparación (con el sitio de db y Rails ejecutándose en el cuadro de Debian), los caracteres de los símbolos aparecen correctamente cuando se muestran desde Rails. Por ejemplo, el Yuan chino aparece como 元 en mi navegador, no å … ƒ como se muestra dentro de la base de datos.

Cuando descargo esos datos a mi máquina de desarrollo OS X local y ejecuto db y Rails localmente, veo la representación desde dentro del DB (å … ƒ) en mi navegador, no el carácter como veo en la puesta en escena.

La depuración he hecho

Me he asegurado de que todos los encabezados de Content-Type vuelvan como utf8 desde cada servidor web (local, por etapas).

Mi servidor mysql local y el servidor de pruebas están configurados para usar utf8 como juego de caracteres predeterminado. Estoy usando “set names ‘utf8′” antes de hacer cualquier llamada.

Incluso puedo conectarme a la base de datos de mi host OS X Rails, y sigo viendo los caracteres å … ƒ que representan el yuan. Supongo que entonces, quizás haya un problema con mi cliente local de mysql, pero no puedo averiguar cuál es el problema.

Tal vez esto podría dar una pista

Para hacerlo aún más confuso, si pego el carácter 元 en la base de datos en mi máquina local, lo veo en la multa del navegador web. — AUNQUE si pego ese mismo personaje en mi db de ensayo, obtengo un? marque en su lugar en la página de mi sitio de Rails.

Además, localmente en mi máquina de Rails OS X si uso “set names ‘latin1′” antes de mis consultas, todos los caracteres vuelven correctamente. Tenía estas tablas establecidas como latin1 antes, ¿podría ser este el problema?

Alguien, por favor, ayúdame aquí. ¡Me estoy volviendo loco tratando de descubrir qué es lo que está mal!

AHA! Parece que tenía alguna información de tabla codificada en latin1 antes, y cambié de forma estúpida las bases de datos a utf8 sin convertir.

Ejecutando lo siguiente arreglamos esa tabla currency_types:

 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 

Ahora solo tengo que asegurarme de que el otro contenido generado después del conmutador latin1> utf8 no se confunda con eso 🙁

¿Tiene estas dos líneas en su database.yml en la sección correspondiente?

 encoding: utf8 collation: utf8_general_ci 
  1. El problema podría haber sido con su cliente MySQL en la puesta en escena que no es compatible con UTF-8.
  2. Es posible que su configuración local de instalación de ruby ​​OSX no haya declarado las configuraciones adecuadas. Debería tener “encoding: utf8” en “config / database.yml” para la base de datos MySQL. Debería tener “$ KCODE = ‘u'” en “config / environment.rb” para el entorno ruby.

Otro enfoque simple es establecer el tipo de encoding utilizando la SQL Alter de SQL . Puedes hacer esto usando el siguiente script de bash.

 for t in $(mysql --user=root --password=admin --database=DBNAME -e "show tables";);do echo "Altering" $t;mysql --user=root --password=admin --database=DBNAME -e "ALTER TABLE $t CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;";done 

prettificado

  for t in $(mysql --user=root --password=admin --database=DBNAME -e "show tables";); do echo "Altering" $t; mysql --user=root --password=admin --database=DBNAME -e "ALTER TABLE $t CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;"; done 

Mi base de datos ya estaba configurada de forma predeterminada en utf8, pero encontré el mismo problema.

También después de agregar la siguiente meta etiqueta habitual, el problema seguía allí:

  

Luego creé un connection.php dedicado para asegurar que todas las comunicaciones con MySQL estén configuradas en el conjunto de caracteres utf8. Tenga en cuenta que no hay - en utf8 en mysqli_set_charset($bd, 'utf8') !

Aquí está mi Connection.php :

  

Otro archivo php:

  //Other stuff 

Para Rails, ejecute el siguiente fragmento de código en la consola de Rails. Se generará un sql para todas las tablas. Luego ingrese a mysql y ejecute el sql copiado desde la consola de Rails. Alterará todas las tablas de encoding.

 schema = File.open('db/schema.rb', 'r').read rows = schema.split("\n") table_name = nil rows.each do |row| if row =~ /create_table/ table_name = row.match(/create_table "(.+)"/)[1] puts "ALTER TABLE `#{table_name}` CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;" end end 

Puede generar una migración, a la manera de Rails, para cambiar el tipo de intercalación en sus bases de datos:

 rails generate migration ChangeDatabaseCollation 

Luego puedes editar el archivo generado y pegar:

 def change # for each table that will store the new collation execute: execute "ALTER TABLE my_table CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci" end 

Y ejecuta la migración:

 rake db:migrate 

También puede imponer la nueva recostackción en su database.yml:

 development: adapter: mysql2 encoding: utf8 collation: utf8_general_ci 

Para más información sobre migraciones de Rails:

http://edgeguides.rubyonrails.org/active_record_migrations.html

Para más información sobre los tipos de colación:

http://collation-charts.org/