5

所以我有一堆用户,他们都有 user.dj_name 属性。这是模型上经过验证的必要性,但我在这里仍然很谨慎,因为我遇到了问题。

我想获得一堆用户,然后按他们的 dj_name 排序。像这样的东西:

@djs = Event.all.map { |e| e.program.user }.sort_by {|x,y| x.dj_name <=> y.dj_name }

它吸引了所有有活动(节目)的 DJ。它因“NoMethodError:nil:NilClass 的未定义方法‘dj_name’而失败”

所以我尝试了:

@djs = Event.all.map { |e| e.program.user }
@djs.compact.sort_by! {|x,y| x.dj_name <=> y.dj_name rescue nil}

而且它没有排序。如果没有“rescue nil”子句,我会得到同样的错误。

如果我拒绝!如果对象为零,我什么也得不到。

> @djs.reject! {|d| d.nil? }
=> nil 

似乎数组中的所有对象都不是 nil,排序机制给了我错误,拯救它只会停止排序过程并返回一个未更改的数组。

停止?

4

2 回答 2

2

使用sort!,不使用sort_by!

sort_by!将单个参数传递到其块中。所以,当你打电话时.sort_by! {|x,y| ... }y总是nil

的目的sort_by!是按键而不是元素进行排序。该块获取单个元素,并且必须返回元素的键以用于排序。

在这段代码中:

@djs.compact.sort_by! {|x,y| x.dj_name <=> y.dj_name rescue nil}

该块nil作为每个元素的键返回。结果,没有排序发生。

顺便说一句,我同意@MurifoX 的观点,在这种特殊情况下,您应该使用数据库提供的排序。

于 2013-06-06T23:36:48.387 回答
2

对此类任务使用数据库排序。您可以使用以下方法恢复查询:

Event.all(:include => {:program => :user}, :order => 'users.dj_name')

解耦此查询将导致include方法在您的模型上建立连接关联并在您的查询上order创建一个。ORDER BY

于 2013-06-06T22:56:10.287 回答