Rails在sort_by中通过查找值来应用条件

时间:2018-12-27 21:16:44

标签: ruby-on-rails

我正在按照员工的名字对员工列表进行排序,并带有以下内容:

TAGS = {
'Region Manager' => 1,
'Region Sales Manager' => 2,
'General Manager' => 3,
'Residential Sales Manager' => 4,
'Commercial Sales Manager' => 5,
'Other' => 6
}.freeze

def sorting_by_title(employees)
 employees.sort_by do |x|
   TAGS[x[:title]]
 end
end

工作正常,但是...如果雇员的姓氏是Smith,并且需要先于其他人,我还需要进行其他排序。

所以我尝试做类似的事情:

return TAGS[x[:title]] unless x.last_name == "Smith"

不起作用。在显示页面上使用2:Integer的未定义方法“ each”错误了。

所以我的想法是我将建立另一种查找姓氏的方法。

def nepotism(employees)
 employees.group_by do |emp|
   case emp.last_name
   when /Smith/ then :moocher
   end
 end
end

所以我尝试然后像这样引用它:

return TAGS[x[:title]] unless x.nepotism
return TAGS[x[:title]] unless x.moocher

这些都不起作用。裙带关系以#的未定义方法“裙带关系”结束,而Moocher则以相同的方式结束。然后我意识到一个简单的查询会更好一些:

def nepotism
 @nepotism = Employee.where(last_name: "Smith")
end

如果通过标记与Smith和THEN匹配,是否有更好的方法来按姓氏排序?

2 个答案:

答案 0 :(得分:1)

这是一个很好的技巧:在ruby中,您可以比较数组。因此,将它们用作sort_by中的值。将它们逐元素进行比较。如果为ary1[0] < ary2[0],则无论其余元素如何,ary1都将小于ary2。

 employees.sort_by do |x|
   [
     x.last_name == "Smith" ? 0 : 1, # all zeroes come before all ones
     TAGS[x[:title]] # your main ordering parameter
   ]
 end

如果有许多史密斯,并且您需要按它们之间的标题对它们进行排序,这将非常有效。如果只有一个史密斯,那么@Björn的解决方案会更简单。

答案 1 :(得分:1)

像这样组合他们

IntStream.rangeClosed

您也可以在数据库中执行此操作(假设此处为Postgresql)

employees.sort_by do |x|
  x.last_name == "Smith" ? 0 : TAGS[x[:title]]
end