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

cod*_*ver 11 sql activerecord ruby-on-rails

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

我想要显示所有已分类标题的电影.我希望它不区分大小写.

我试过这样做:

Movie.all(:conditions => ["lower(title) = ?", title.downcase],:order => "title DESC")
=>undefined local variable or method `title' for #<MoviesController:0xb4da9a8>
Run Code Online (Sandbox Code Playgroud)

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

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

谢谢!

Ant*_*rto 17

使用where与否all

Movie.where("lower(title) = ?", title.downcase).order("title DESC")
Run Code Online (Sandbox Code Playgroud)

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

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

Movie.order("lower(title) DESC").all
Run Code Online (Sandbox Code Playgroud)

  • 在 Rails 6 中,这将不再被允许,请确保在 Arel.sql() (https://github.com/rails/rails/commit/310c3a8f2d043f3d00d3f703052a1e160430a2c2) 中包装任何这样的 SQL (2认同)

Dog*_*ert 7

你必须这样做:

Movie.order("lower(title) DESC").all
Run Code Online (Sandbox Code Playgroud)


Gar*_*ner 5

A more robust solution is to use arel nodes. I'd recommend defining a couple scopes on the Movie model:

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

scope :for_title, (title)-> {
  where(arel_table['title'].lower.eq title.downcase)
}
Run Code Online (Sandbox Code Playgroud)

and then call Movie.for_title(title).order_by_title

The advantage over other answers listed is that .for_title and .order_by_title won't break if you alias the title column or join to another table with a title column, and they are sql escaped.

Like rickypai mentioned, if you don't have an index on the column, the database will be slow. However, it's bad (normal) form to copy your data and apply a transform to another column, because then one column can become out of sync with the other. Unfortunately, earlier versions of mysql didn't allow for many alternatives other than triggers. After 5.7.5 you can use virtual generated columns to do this. Then in case insensitive cases you just use the generated column (which actually makes the ruby more straight forward).

Postgres has a bit more flexibility in this regard, and will let you make indexes on functions without having to reference a special column, or you can make the column a case insensitive column.