Search code examples
ruby-on-railspostgresqlutf-8ruby-object-mapper

What is the correct way to use UTF-8 characters with PostgreSQL and Ruby Object Mapper?


I've tried many random shots in the dark, such as:

  config.gateways[:default] = [:sql, database_url, encoding: 'UTF8']

And all variations on UTF8, e.g., utf8, utf-8, unicode, Unicode.

  • I've tried setting the shell env's LC_CTYPE to UTF8.
  • I've tried setting the client_encoding parameter on the connection URL.
  • I've verified that the database has an encoding of UTF8, i.e., SHOW server_encoding.
  • I've verified that ROM's Sequel connection reports a client encoding of UTF8 right before actual use, i.e., SHOW client_encoding;
  • I've verified that I can insert and read back UTF-8 characters with the same database using psql.
  • I've verified I can insert and read back UTF-8 characters with the same database using Rails' ActiveRecord.

But when I give ROM non-ASCII, UTF-8 characters to insert, the characters are replaced with '�' somewhere along the way to PostgreSQL.

What is the correct way to setup ROM and use it with UTF-8 characters?


Solution

  • Hmm we pass connection options straight to Sequel, then if you specify during connection configuration option like encoding: utf-8 it will work

    ROM::Configuration.new(:sql, "postgres://...", { encoding: utf-8 })

    require 'rom'
    require 'rom-sql'
    
    DATABASE_URL = ENV.fetch('DATABASE_URL', 'postgres://localhost/rom')
    setup = ROM::Configuration.new(:sql, DATABASE_URL, encoding: 'unicode')
    rom = ROM.container(setup)
    
    conn = setup.default.connection
    conn.drop_table?(:users)
    conn.create_table :users do
      String :name
    end
    
    class Users < ROM::Relation[:sql]
    end
    
    setup.register_relation(:users)
    
    rom.relations.users.insert(:name => "Pöter")
    
    p rom.relations.users.to_a