按多个字段排序ActiveRecords

时间:2014-07-23 17:01:54

标签: ruby activerecord

我正在尝试使用2个字段created_atjob_code对查询结果进行排序。我遇到的问题是job_code由一个包含数字和字母的字符串组成,显然sort_by方法并不喜欢。

def structure_jobs(jobs)
  jobs.sort_by{|j| [j.created_at, j.job_code]}.reverse
end

Sample Data:
created_at     |    job_code
Jul-22-2014         140987E
Jul-22-2014         1482923
Jul-22-2014         140987Z
Mar-15-2014         12N7Y65

Results Wanted:
created_at     |    job_code
Jul-22-2014         1482923
Jul-22-2014         140987Z
Jul-22-2014         140987E
Mar-15-2014         12N7Y65

我按DESC created_at顺序排序,因此最新到最旧。如果它们在日期匹配,那么按job_code排序可能是DESC / ASC顺序并不重要,只要它们仍然按照各自的顺序排序。

1 个答案:

答案 0 :(得分:1)

我认为你应该在数据库中进行排序:

query.order('created_at desc, job_code asc')

但是如果你必须在Ruby中排序那么为什么不使用sort而不是sort_bysort_by对于简单的事情很有用,但是当你需要对其中一个组件进行反向排序而你不能(干净地)使用简单的技巧来否定一个数字来反转顺序时需要奇怪的扭曲。使用sort您可以说:

jobs.sort do |a, b|
  if((b.created_at <=> a.created_at) == 0)
    a.job_code <=> b.job_code
  else
    b.created_at <=> a.created_at
  end
end

created_at上降序排序并在job_code上升序排序。对于升序created_at和降序job_code,您可以撤销ab s:

jobs.sort do |a, b|
  if((a.created_at <=> b.created_at) == 0)
    b.job_code <=> a.job_code
  else
    a.created_at <=> b.created_at
  end
end

如果您对created_atjob_code按升序排序

jobs.sort_by{|j| [j.created_at, j.job_code]}

应该可以正常工作。如果你要按顺序排序,那么:

jobs.sort_by{|j| [j.created_at, j.job_code]}.reverse

应该可以正常工作。

演示(基于falsetru):http://ideone.com/L2vMST