Я недавно отряхнул свой старый проект Ruby on Rails. В прошлом у меня никогда не было проблем с выполнением всех тестов, но теперь есть один тест, который дает мне следующую ошибку:
ActiveRecord :: StatementInvalid: Mysql :: Ошибка: # HY000Неверное сочетание параметров сортировки (latin1_swedish_ci, IMPLICIT) и (utf8_general_ci, COERCIBLE) для операции '=': ВЫБРАТЬ * ИЗ карт, ГДЕ (cards.l1_description = '是' AND .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.
Я не очень хорошо понимаю, как работает тест рейка, но моя рабочая гипотеза заключается в том, что он воссоздает БД с использованием 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, делать это. Кто-нибудь может помочь?
Для чего бы то ни было, базы данных для тестирования и разработки были созданы как
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, но мне не повезло с предложениями там.