按日期(或任何其他列)对ActiveRecord返回的数组进行排序

use*_*154 63 ruby arrays activerecord ruby-on-rails

如何按created_at日期列对ActiveRecord查询返回的数组进行排序?

执行查询后会发生这种情况.

请不要告诉我在查询中执行此操作,因为我需要在视图中执行此操作.

Chu*_*uck 124

Ruby支持开箱即用的分类.

sorted = @records.sort_by &:created_at
Run Code Online (Sandbox Code Playgroud)

但是,这似乎与显示无关,可能属于控制器.

  • @Bill D:这与事实完全相反.`sort`更灵活 - 你指定整个比较谓词,而使用`sort_by`你只需告诉它*要比较什么*它使用默认的`sort`谓词.这种情况,你调用一个方法并根据结果排序,是很常见的 - "sort_by"只是一种更简洁的写作方式. (3认同)
  • 可枚举#sort_by非常适合这类事情,比使用Enumerable#sort的其他示例要好得多. (2认同)

小智 33

虽然Ruby Enumerable非常棒,但ActiveRecord查询实际上会返回一个ActiveRecord :: Relation,其查询尚未被评估(延迟加载),并且可以调用其上的order方法将此处理卸载到数据库,在那里它将扩展比基于可枚举的策略好得多.

使用Enumerable进行排序也会混淆在数据库中进行分页.没有什么可以阻止在视图中应用订单策略.但是,我倾向于将其放在模型的范围内.

sorted = @records.order(:created_at)
Run Code Online (Sandbox Code Playgroud)


小智 26

只需在集合上调用sort,传入代码块,告诉Ruby你想要它如何排序:

collection.sort { |a,b| a.created_at <=> b.created_at }
Run Code Online (Sandbox Code Playgroud)

  • 为了记录,这将不比我给出的版本有效. (6认同)
  • 在这种情况下,与`.sort_by`相比,这样效率太低.请查看Chuck的其他答案. (2认同)

Saj*_*aza 6

请查看这一内容,并检查其复杂性。

Model.all.sort_by{|m| m.created_at} #=> O(log n)

#versus

Model.order(“created_at DESC”) #=> O(1)
Run Code Online (Sandbox Code Playgroud)


小智 5

排序 ActiveRecord 数组的最佳方法是使用默认方法顺序

@users.order(:created_at)

这是最快和最正确的解决方案,因为在这种情况下,它从 db 返回排序的数组,并且您无需在类中使用任何其他操作,例如,如果您将使用建议sort_by,它将循环抛出数组的每个元素,之后它不会是一个 ActiveRecord 数组,在我看来并不酷。

order 可以使用字符串和sumbols,非常有用,并且需要多个参数

@users.order('created_at asc, first_name desc, last_name asc')