Rorra's blog Senior Developer

July 30, 2010

Rails 3, mysql and UTF-8

Filed under: Ruby — admin @ 3:01 PM


So, have you started to work with rails 3? Did you realize that your UTF-8 databases doesn’t work nice with mysql? This is because the mysql gem works with ASCII-8BIT encoding, but ruby 1.9 and rails 3 works with UTF-8 encoding, so when you create a model into the database, everything works fine, but when you work with those models, it doesn’t works so nice and you don’t get what you stored.
What’s the solution? Well, there are actually three solutions, the most recommended, use mysql2, in order to do this, edit your Gemfile and include:

gem "mysql2"

and then, edit your databases.yml file, and change the adapter to mysql2

development:
  adapter: mysql2
  database: fun_development
  user: root
  password:
  encoding: utf8

Another solution, is just instead of using the “mysql” gem, use the “ruby-mysql” gem, but it’s pretty slow because it’s a 100% ruby gem.

gem "ruby-mysql"

The last solution is a monkey patch, but its also slow to use it, so I really recommend using the mysql 2 gem

require 'mysql'

class Mysql::Result
  def encode(value, encoding = "utf-8")
    String === value ? value.force_encoding(encoding) : value
  end

  def each_utf8(&block)
    each_orig do |row|
      yield row.map {|col| encode(col) }
    end
  end
  alias each_orig each
  alias each each_utf8

  def each_hash_utf8(&block)
    each_hash_orig do |row|
      row.each {|k, v| row[k] = encode(v) }
      yield(row)
    end
  end
  alias each_hash_orig each_hash
  alias each_hash each_hash_utf8
end
Be Sociable, Share!

10 Comments »

  1. Thanks a lot!!!

    Comment by Thiago — November 21, 2010 @ 8:06 PM

  2. [...] rapide passage sur StackOverflow m’a mené vers l’article suivant où il est mentionné que le gem mysql n’est pas compatible avec l’encodage UTF-8. Et [...]

    Pingback by [Rails 3] Méfiez vous du gem mysql ! « FIX YOUR CODE — March 9, 2011 @ 9:24 PM

  3. Thanks for your article. It helps me a lot!

    Comment by david — April 20, 2011 @ 10:25 AM

  4. Buenos días, soy nuevo en rails, vengo de .net y me cuesta un poco, estoy buscando una forma de que se creen los modelos automáticamente en rails, debido a que tengo una base de datos de muchas tablas, estuve leyendo que el Magic Model Generator in Rails no funciona en rails 3, conoces alguna forma de hacer esto?

    Comment by Luis — May 5, 2011 @ 12:37 PM

  5. Es que si tenes una base de datos con muchas tablas, y generas los modelos, tarde o temprano vas a terminar utilizando esos modelos de alguna manera, por ende, no veo razón para generarlo automáticamente.
    Generar un modelo por cada tabla no es un gran lío, si tu tabla se llama “clients”, basta con hacer
    class Client < ActiveRecord::Base
    end
    y listo, ya tenes tu modelo, el tema esta en implementar las relaciones con otras tablas (en especial si tus tablas no siguen el estandard de rails) y si tenes nombres no estandarizados, vas a terminar haciendo cosas como:
    class Client < ActiveRecord::Base
    set_table_name "cliente"
    has_many :users, :foreign_key => “USER_ID”
    end
    que igual sigue siendo algo muy sencillo.
    Por otro lado, el tema de activerecord, como definir los modelos, las relaciones, y demás, suponiendo que tengas unas 100 tablas, no debería de llevarte más de 30-60 minutos, te recomiendo que hagas todo el tutorial que viene en el libro “agile web development with rails”, que te leas bien el capitulo más adelante en el libro sobre ActiveRecord y recién ahí escribas los modelos para tu base de datos, porque lo que tenes que hacer es realmente algo muy sencillo de hacer en rails si tenes los conocimientos básicos del framework.
    Saludos

    Comment by admin — May 6, 2011 @ 11:37 AM

  6. So are you saying that the database created with MySQL has to be created as UTF-8 database in order to work correctly with Ruby 1.9 and Rails 3.x ?

    Comment by Web Hosting — October 7, 2011 @ 10:26 AM

  7. No, I’m saying that in order to support multi character encoding in rails 3 with utf8 (i.e: êûáú) you need the mysql2 gem, while on rails 2 applications you didn’t have any trouble by using the mysql gem.

    Comment by admin — October 7, 2011 @ 2:39 PM

  8. where i need to patch above code

    Comment by amruth — February 21, 2012 @ 10:03 AM

  9. Guys please guide me where i need to patch this

    require ‘mysql’

    class Mysql::Result
    def encode(value, encoding = “utf-8″)
    String === value ? value.force_encoding(encoding) : value
    end

    def each_utf8(&block)
    each_orig do |row|
    yield row.map {|col| encode(col) }
    end
    end
    alias each_orig each
    alias each each_utf8

    def each_hash_utf8(&block)
    each_hash_orig do |row|
    row.each {|k, v| row[k] = encode(v) }
    yield(row)
    end
    end
    alias each_hash_orig each_hash
    alias each_hash each_hash_utf8
    end

    Comment by amruth — February 21, 2012 @ 10:03 AM

  10. You can put it on any file inside config/initializers, like config/initializers/utf_patch.rb

    Comment by admin — February 29, 2012 @ 2:35 AM

RSS feed for comments on this post. TrackBack URL

Leave a comment

Powered by WordPress