JumpstartLab 的说明中缺少一个步骤。设置语言环境后,您还需要设置环境以在运行 initdb 之前使用它。问题出在JumptartLab's instructions 的“区域设置”部分:
$ sudo /usr/sbin/update-locale LANG=en_GB.UTF-8 LC_ALL=en_GB.UTF-8 # I am in GB, you may want US
$ . /etc/default/locale # missing step
现在检查您的区域设置(请参阅下面的“它是如何发生的?”如果您不执行缺少的步骤会发生什么)
$ locale # look, UTF-8 encodings
LANG=en_GB.UTF-8
LANGUAGE=
LC_CTYPE="en_GB.UTF-8"
LC_NUMERIC="en_GB.UTF-8"
LC_TIME="en_GB.UTF-8"
LC_COLLATE="en_GB.UTF-8"
LC_MONETARY="en_GB.UTF-8"
LC_MESSAGES="en_GB.UTF-8"
LC_PAPER="en_GB.UTF-8"
LC_NAME="en_GB.UTF-8"
LC_ADDRESS="en_GB.UTF-8"
LC_TELEPHONE="en_GB.UTF-8"
LC_MEASUREMENT="en_GB.UTF-8"
LC_IDENTIFICATION="en_GB.UTF-8"
LC_ALL=en_GB.UTF-8
现在,当您来到“创建数据库实例并添加用户”部分时,initdb 命令(他们没有使用--encoding= 参数指定)可以从环境中计算出 UTF-8 编码.这使其进入创建其他数据库的 template1 数据库。因此它不会与平台验证器的config/database.yml 中的development 和test 条目指定的utf8 编码冲突,当您运行rake db:create 时会读取该编码。
让它消失
如果您正在阅读本文是因为您已经按照 JumpstartLab 的说明操作并在运行 rails db:create 时遇到了问题,那么您需要在 VirtualBox 中更正 Postgres 安装的设置。问题出在 template1 数据库中,所有其他数据库都是从该数据库创建的。
sudo su postgres 和psql template1 的正确模板1 然后按照blog 中的说明遵循此gist。
或者更彻底地,删除 Postgres:sudo apt-get --purge remove postgresql\*,然后如上所述更正您的语言环境和环境,并从“PostgreSQL 安装”重新执行 JumpstartLab 的说明:sudo apt-get install postgresql libpq-dev。
这是怎么发生的?
JumpstartLab 的说明会引导您安装 Ubuntu 12.04 LTS 32 位机器。在更改语言环境或安装 Postgres、Ruby 或 Rails 之前,使用 vagrant up 启动该框并使用 vagrant ssh 连接到它并查看语言环境设置。您会看到区域设置语言设置为 (en)glish 和地区 US 但没有编码,例如 UTF-8 或 LATIN1:
vagrant@precise32:~$ locale
LANG=en_US
LANGUAGE=
LC_CTYPE="en_US"
LC_NUMERIC="en_US"
LC_TIME="en_US"
LC_COLLATE="en_US"
LC_MONETARY="en_US"
LC_MESSAGES="en_US"
LC_PAPER="en_US"
LC_NAME="en_US"
LC_ADDRESS="en_US"
LC_TELEPHONE="en_US"
LC_MEASUREMENT="en_US"
LC_IDENTIFICATION="en_US"
LC_ALL=en_US
因此,当您安装 Postgres 时,它不会从其主机获得有关编码的指示,不幸的是默认为 LATIN1 而不是 UTF-8。 JumpstartLab 的说明让您认为您已经设置了语言环境:
vagrant@precise32:~$ sudo /usr/sbin/update-locale LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8
但你没有:
vagrant@precise32:~$ locale # should login again or source /etc/default/locale before doing this
LANG=en_US
LANGUAGE=
LC_CTYPE="en_US"
LC_NUMERIC="en_US"
LC_TIME="en_US"
LC_COLLATE="en_US"
LC_MONETARY="en_US"
LC_MESSAGES="en_US"
LC_PAPER="en_US"
LC_NAME="en_US"
LC_ADDRESS="en_US"
LC_TELEPHONE="en_US"
LC_MEASUREMENT="en_US"
LC_IDENTIFICATION="en_US"
LC_ALL=en_US
vagrant@precise32:~$
因此,当您现在安装 Postgres 时,您会获得模板 1 的默认 LATIN1 编码:
vagrant@precise32:/vagrant$ psql -l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
-----------+----------+----------+---------+-------+-----------------------
postgres | postgres | LATIN1 | en_US | en_US |
template0 | postgres | LATIN1 | en_US | en_US | =c/postgres +
| | | | | postgres=CTc/postgres
template1 | postgres | LATIN1 | en_US | en_US | =c/postgres +
| | | | | postgres=CTc/postgres
(3 rows)
这与运行 rake db:create 时使用的 platform_validator 的 config/database.yml 中的 development 和 test 条目指定的 utf8 编码冲突。