尽管在Heroku上使用Rails设置了新的参数组,但无法在RDS中存储UTF-8

我正在使用Amazon RDS作为数据库在Heroku上设置一个新的Rails(2.3.5)应用程序实例。 我想把UTF-8用于一切。 由于默认情况下RDS不是UTF-8,因此我设置了一个新的参数组并将数据库切换为使用该参数,基本上是这样的 。 似乎工作:

SHOW VARIABLES LIKE '%character%'; 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 /rdsdbbin/mysql-5.1.50.R3/share/mysql/charsets/ 

此外,我已成功设置Heroku以使用RDS数据库。 在rake db:migrate之后,一切看起来都很好:

 CREATE TABLE `comments` ( `id` int(11) NOT NULL AUTO_INCREMENT, `commentable_id` int(11) DEFAULT NULL, `parent_id` int(11) DEFAULT NULL, `content` text COLLATE utf8_unicode_ci, `child_count` int(11) DEFAULT '0', `created_at` datetime DEFAULT NULL, `updated_at` datetime DEFAULT NULL, PRIMARY KEY (`id`), KEY `commentable_id` (`commentable_id`), KEY `index_comments_on_community_id` (`community_id`), KEY `parent_id` (`parent_id`) ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; 

在标记中,我包括:

  

另外,我已经设定:

 production: encoding: utf8 collation: utf8_general_ci 

…在database.yml中,虽然我不确定在这种情况下是否正在做任何设置,因为Heroku在连接到RDS时似乎正在做自己的配置。

现在,我通过应用程序中的表单输入评论:“Úbe®ƒåiL”,但在数据库中我有“Úbe®ƒåiL”

当Rails将其从数据库中加载回来并将其呈现给页面时,它看起来很好,所以无论它采用哪种方式,它都会撤消另一种方式。 如果我查看Sequel Pro中的RDS数据库,如果我将编码设置为“UTF-8 Unicode via Latin 1”,它看起来很好。 所以看来Latin-1在某个地方偷偷摸摸。

当连接到本地MySQL数据库时,一切都在开发中。

有人必须先做过这个,对吧? 我错过了什么?

有一种更简单的方法。 您可以在数据库连接字符串中指定编码。 编辑RDS加载项,并追加?encoding=utf8&collation=utf8_general_ci

对我来说工作得很好,没有改变项目。

例如:

  mysql://user:pass@abc.rds.amazonaws.com/my-db?encoding=utf8&collation=utf8_general_ci 

参考: http : //blog.arvidandersson.se/2011/09/27/setting-activerecord-connection-to-utf8-on-heroku

最后,我通过在environment.rb中的Rails :: Initializer.run块中添加以下内容来解决我的问题

 class Rails::Configuration def database_configuration # Heroku overwrites the database.yml file without setting any encoding when deploying to outside server (like Amazon RDS) require 'erb' YAML::load(ERB.new(IO.read(database_configuration_file)).result).each_value {|env| env.merge!({"encoding" => "utf8", "collation" => "utf8_general_ci"}) } end end 

Heroku会覆盖database.yml文件,不包含任何编码或联盟设置。 通过这样黑客攻击,在进行数据库连接之前始终合并正确的设置。