我在一个页面(Rails视图)上显示作者,如下所示:

Author.where(featured: true).where.not(username: nil).order(:priority, :name)

然而,我最近添加了一个新的型号Photographer,我想结合摄影师和作者,并以类似的方式对他们进行排序.它们共享大部分相同的列.

我试过了:

combined = (Author.where(featured: true).where.not(username: nil) + Photographer.where(featured: true).where.not(username: nil))

combined.order(:priority, name)
=> NoMethodError (undefined method `order' for #<Array:0x00005573bc2ab3b0>)

combined.sort_by {|item| [item.priority, item.name]}
=> ArgumentError (comparison of Array with Array failed)

需要注意的是,在某些情况下,priority相当于nil.因此,在这种情况下,它应该按名称排序.

如有任何帮助,我们不胜感激!

推荐答案

问题是,nil只能与nil相比:

       nil <=> nil  # => 0         # -1, 0, 1 are good
"priority" <=> nil  # => nil       # `nil` means not comparable 
                                   # and you get an error from `sort_by`

解决方案是避免将nil与其他任何东西进行比较,或者显式地处理这种比较.

您可以使用sort并自己对nil进行排序:

ary = (Author.all + Photographer.all)

ary.sort do |a, b|
  if a.priority && b.priority              # priority <=> priority
    a.priority <=> b.priority
  elsif a.priority                         # priority <=> nil
    -1                # nil is lower 
  elsif b.priority                         #      nil <=> priority
    1                 # priority is higher
  else                                     #      nil <=> nil
    a.name <=> b.name # break the tie
  end
end

您可以将数组一分为二,有优先级和无优先级,并对每个数组进行排序.这样,将prioritypriority进行比较;将nilnil进行比较,后者为0,然后回退到比较name(与上面的sort类似,但elsif‘s永远不匹配):

ary.partition(&:priority).flat_map do |part|
  part.sort_by { |i| [i.priority, i.name] }
end

或者,一个更愚蠢的方法(也更快)是让nil成为最后的东西:

ary.sort_by { |i| [i.priority||"zzz", i.name] }

Ruby-on-rails相关问答推荐

复制我的活动时,活动描述没有复制过来

Ruby on rails 查询不知道怎么写

在 Rails 中进行 Http 基本身份验证

ViewModel 和 Controller 有什么区别?

Rails 3 的data-method='delete'如何优雅地降级?

如何使用 Vim 插入 ERB 标签?

为 ActionMailer 渲染不同的视图(模板)

如何使用 capistrano deploy 定位特定的提交 SHA

如何在 ruby​​ on rails 中获取控制器和操作列表?

Rails 3.1 在开发模式下非常慢,因为assets资源 ,怎么办?

Ruby gem 命名约定

在具有唯一约束的关联中使用 Rails 中的 factory_girl.得到重复的错误

Rails 中是否有 HTML 安全截断方法?

Rails 3.0 中的 f.error_messages

如何在 Ruby on Rails 的内存缓存存储中列出键?

我如何在具有活动记录的 Rails 中使用两个不同的数据库?

禁用 JS/Ajax 请求时的 ActionController::InvalidAuthenticityToken

has_many :通过 class_name 和 foreign_key

ruby 方法名称中的变量

ActiveRecord 何时会保存关联?