Rails sort_by on Array因为nil值而抛出ArgumentError - 它不应该根据数据库排序吗?

时间:2016-02-24 13:08:25

标签: ruby-on-rails

我使用sort_by:

在Rails 4中对数组进行排序
sort_column = 'experience_in_months'
@userstoshow=@userstoshow.sort_by(&:"#{sort_column}")

这会抛出错误

  

SNIP 中发生了ArgumentError:

     

Fixnum与nil的比较失败

这是一个奇怪的问题,因为我记得早些时候读过这个。它应该根据使用的数据库将nil值放在第一位或最后一位。我正在使用PostGreSQL。

我记得几天前这个工作非常完美 - 它只是将nil值放在我桌面的顶部。

这不是一个难以解决的问题 - 我可以取出零值,对剩下的值进行排序,然后加回零值。但我想清楚这是一种随机行为还是如预期的那样。

2 个答案:

答案 0 :(得分:1)

@arunt,我猜你有@userstoshow类型的User对象或类似的东西。

现在,当您使用 Ruby sort_by时,它会对集合进行枚举并尝试a <=> b,这是一个等效的代码段。

@userstoshow = @userstoshow.sort_by do |a, b|
  a.experience_in_months <=> b.experience_in_months
end

现在Ruby不知道如何将Fixnum与NilClass进行比较,这是一个类似的案例

[1, 2, 3, nil].sort => ArgumentError: comparison of Fixnum with nil failed

所以问题是你的User对象的某些对象正在返回nil而不是Fixnum值。

因此,您可以更改sort_by以包含代码块,也可以修改User对象以返回默认值nil。

答案 1 :(得分:1)

这是预期的行为

数据库排序仅适用于数据库查询

一旦数据不在数据库中,Ruby就可以完全控制并排除订购规则。 数据库规则不再适用,因为数组在任何地方都使用,没有任何宝石希望它们以这种方式被破坏。

利用nil.to_i0的事实,您可以使用以下内容:

attribute_proc = sort_column.to_sym.to_proc
@userstoshow = @userstoshow.sort_by { |x| attribute_proc.call(x).to_i }

...而且您正在替换该值,因此您可以使用sort_by!,而不是sort_by

attribute_proc = sort_column.to_sym.to_proc
@userstoshow.sort_by! { |x| attribute_proc.call(x).to_i }

看起来有点吓人。那是因为你没有使用固定的属性名称。否则,它将是:

@userstoshow.sort_by! { |x| x.experience_in_months.to_i }