我有一个像这样的ActiveRecord模型:
create_table "books" do |t|
t.string "title"
end
class Book < ActiveRecord::Base
default_scope :order => 'lower(title) DESC'
end
正如您所看到的,我想按 title
属性的小写形式排序,但这会在数据库级别上造成性能损失 . 可以使用不同的数据库以不同的方式纠正此命中 . 例如,在PostgreSQL或Oracle中,您可以创建基于函数的索引:
CREATE INDEX lowercase_book_title_index ON book (lower(title));
SQLite3没有基于函数的索引,因此您必须指定排序规则:
CREATE INDEX lowercase_book_title_index ON book (title COLLATE NOCASE);
我没有研究过你是如何用MySQL做的,但我确定有一种方法(整理?虚拟列?) .
无论如何,我希望以正确的Rails方式进行数据库无关的迁移 . 我当然可以创建一个这样的简单索引:
add_index :books, :title
但是这个生成的索引区分大小写 . 我意识到我可以编写一个依赖于数据库的迁移,但它不是很优雅 . 它也不实用 - 我经常发现自己在我的开发工作站上使用SQLite3,在 生产环境 中使用PostgreSQL . add_index的可用选项处理索引名称,唯一性和长度 . 我是否忽略了一种方法来完成我在这里要做的事情?
2 回答
简答:不是
答案很长:不是,因为并非所有数据库引擎都支持它支持Rails,或者以一种非常不同的方式 . 如果您确定所有数据库引擎都支持它,那么请为ActiveRecord开发人员提交功能请求 .
请记住:在ActiveRecord迁移中,您只能执行所有数据库引擎支持的操作,特定于数据库的内容需要从迁移中分离初始化 .
我建议从db:migrate之后运行的独立rake任务设置此归类 . 在我更大的应用程序中,我使用
rake setup
,我可以执行此特定步骤 .我从未对这种排序有任何问题 . 基本上,你想要的是结果以这种方式排序:
如果这是正确的并且您使用的是mysql,则可以在database.yml中指定排序规则,尝试:
utf8_general_ci的意思是“以与语言无关的方式与utf8进行整理并且不区分大小写” .
这应该可以解决问题 .