Я недавно очистил старый проект Ruby on Rails. Раньше у меня никогда не было проблем с прохождением всех тестов, но теперь есть один тест, который дает мне следующую ошибку:
ActiveRecord :: StatementInvalid: Mysql :: Error: # HY000Illegal mix of collations ( latin1_swedish_ci, IMPLICIT) и (utf8_general_ci, COERCIBLE) для операции '=': SELECT * FROM cards WHERE (cards.l1_description = '是' AND cards.l2_word = '')
Итак, я перехожу к своей тестовой базе данных и спрашиваю:
mysql> use flashcard_test
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> show full columns from cards;
+----------------+--------------+-------------------+------+-----+---------+----------------+---------------------------------+---------+
| Field | Type | Collation | Null | Key | Default | Extra | Privileges | Comment |
+----------------+--------------+-------------------+------+-----+---------+----------------+---------------------------------+---------+
| id | int(11) | NULL | NO | PRI | NULL | auto_increment | select,insert,update,references | |
| l2_word | varchar(255) | latin1_swedish_ci | YES | | NULL | | select,insert,update,references | |
| l1_description | text | latin1_swedish_ci | YES | | NULL | | select,insert,update,references | |
| l1_id | int(11) | NULL | YES | | NULL | | select,insert,update,references | |
| l2_id | int(11) | NULL | YES | | NULL | | select,insert,update,references | |
+----------------+--------------+-------------------+------+-----+---------+----------------+---------------------------------+---------+
5 rows in set (0.01 sec)
Как видите, сортировка - latin1_swedish_ci, и, предположительно, если бы это было «utf8_general_ci», мои проблемы были бы решены. К счастью, моя база данных для разработки уже в порядке, так что я иду и
rake db:test:clone_structure
, а затем снова в MySql и снова проверяю в тестовой db
mysql> show full columns from cards;
+----------------+--------------+-----------------+------+-----+---------+----------------+---------------------------------+---------+
| Field | Type | Collation | Null | Key | Default | Extra | Privileges | Comment |
+----------------+--------------+-----------------+------+-----+---------+----------------+---------------------------------+---------+
| id | int(11) | NULL | NO | PRI | NULL | auto_increment | select,insert,update,references | |
| l2_word | varchar(255) | utf8_general_ci | YES | | NULL | | select,insert,update,references | |
| l1_description | text | utf8_general_ci | YES | | NULL | | select,insert,update,references | |
| l1_id | int(11) | NULL | YES | | NULL | | select,insert,update,references | |
| l2_id | int(11) | NULL | YES | | NULL | | select,insert,update,references | |
+----------------+--------------+-----------------+------+-----+---------+----------------+---------------------------------+---------+
5 rows in set (0.00 sec)
А, теперь все выглядит хорошо, так что еще раз я
rake test
Но у меня снова возникает та же проблема, и когда я проверьте мою тестовую базу данных, я обнаружил, что столбец сопоставления был сброшен на latin1_swedish_ci.
Я не очень хорошо понимаю, как работает тест rake, но моя рабочая гипотеза состоит в том, что он воссоздает базу данных с помощью schema.rb. Теперь, в одной из моих миграций, у меня есть
class CreateCards < ActiveRecord::Migration
def self.up
create_table :cards, :options => "DEFAULT CHARACTER SET=utf8 COLLATE=utf8_general_ci" do |t|
t.column :english_word, :string
t.column :chinese_description, :text
end
end
def self.down
drop_table :cards
end
end
И это, по-видимому, решило проблему сопоставления. (У меня есть еще одна миграция, которая переименовывает english_word и chinese_description в l2_word и l1_description соответственно.) Но эта информация не попала в schema.rb. И каким-то образом, по-видимому, MySql решил предположить, что я хочу latin1_swedish_ci.
Итак, подведем итог, что, я думаю, мне нужно сделать, это как-то отредактировать что-то, чтобы я использовал сопоставление utf8_general_ci, и тогда мои проблемы исчезнут (верно?). Но я не могу понять, как сделать так, чтобы код запускался, когда вы выполняете «rake test». Кто-нибудь может помочь?
Как бы то ни было, базы данных для тестирования и разработки были созданы как
create database flashcard_test default character set utf8 default collate utf8_general_ci;
и
create database flashcard_development default character set utf8 default collate utf8_general_ci;
, а в моем database.yml есть
development:
adapter: mysql
database: flashcard_development
username: root
password:
encoding: utf8
test:
adapter: mysql
database: flashcard_test
username: root
password:
encoding: utf8
collation: utf8_general_ci
http://nhw.pl/wp/2008/09 / 16 / mysql-collate-setting-in-rails-application , похоже, предполагает, что эта проблема имеет какое-то отношение к соединению между RoR и MySql, но мне не повезло с предложениями там.