Rails:ActiveRecord db排序操作不区分大小写

我正在尝试学习rails [通过遵循课程中的SAAS课程]并使用ActiveRecord处理简单的Movie表。

我想显示所有标题已排序的电影。 我希望它不区分大小写。

我试过这样做:

Movie.all(:conditions => ["lower(title) = ?", title.downcase],:order => "title DESC") =>undefined local variable or method `title' for # 

我认为它不承认较低(标题)。

这是实现案件分类的最佳方式吗?

谢谢!

使用where而不是all

 Movie.where("lower(title) = ?", title.downcase).order("title DESC") 

不过真的不明白。 在这里,您将获得所有标题较低的电影等于title.downcase 。 一切都是平等的,你怎么能通过title desc对它进行排序?

按小写标题按字母顺序对所有电影进行排序:

 Movie.order("lower(title) DESC").all 

你必须这样做:

 Movie.order("lower(title) DESC").all 

让MySQL每次执行大写或小写操作都非常昂贵。

我建议使用title列和title_lower列。 这样,您可以在title_lower列上轻松显示和排序大小写不敏感,而无需在每次排序时MySQL执行上限或下限。

请记住索引两者或至少title_lower

更强大的解决方案是使用arel节点。 我建议在Movie模型上定义几个范围:

 scope :order_by_title, -> { order(arel_table['title'].lower.desc) } scope :for_title, (title)-> { where(arel_table['title'].lower.eq title.downcase) } 

然后调用Movie.for_title(title).order_by_title

与列出的其他答案相比,优势在于.for_title.order_by_title如果您将title列别名或连接到另一个带有title列的表,则不会中断,并且它们是sql转义的。

像rickypai 提到的那样 ,如果列上没有索引,数据库将会很慢。 但是,复制数据并将转换应用于另一列是不好的(正常)forms,因为一列可能与另一列不同步。 不幸的是,早期版本的mysql不允许除触发器之外的许多替代方案 。 在5.7.5之后,您可以使用虚拟生成的列来执行此操作。 然后在不区分大小写的情况下,您只需使用生成的列(这实际上使得ruby更直接)。

Postgres在这方面有更多的灵活性,并且可以让您在函数上创建索引而无需引用特殊列,或者可以使列不区分大小写。