通过实例方法订购集合

时间:2018-07-18 10:59:32

标签: ruby-on-rails ruby activerecord

我想先按优先级排序,然后再按时排序:

@ods = Od.order(:priority, :due_date_time)

问题是due_date_time是Od的实例方法,所以我得到

  

PG :: UndefinedColumn:错误:列ods.due_date_time不存在

我已经尝试了以下方法,但是似乎是通过对ID进行排序和映射,然后使用.where再次查找它们,意味着排序顺序丢失了。

 @ods = Od.where(id: (Od.all.sort {|a,b| a.due_date_time <=> b.due_date_time}.map(&:id))).order(:priority)

due_date_time从子关联中调用方法:

  def due_date_time
    run.cut_off_time
  end

run.cut_off_time在这里定义:

  def cut_off_time
    (leave_date.beginning_of_day + route.cut_off_time_mins_since_midnight * 60)
  end

我敢肯定有一种更简单的方法。任何帮助,不胜感激!谢谢。

1 个答案:

答案 0 :(得分:1)

ActiveRecord中的

order与ruby中的sort类似。因此,Od.all.sort在数据库查询Od.all之后运行迭代,运行新的迭代map,然后发送新的数据库查询。另外,Od.all.sort没有意义,因为whereid中包含ids时选择记录,但没有为每个id搜索记录。

更容易执行以下操作:

Od.all.sort_by { |od| [od.priority, od.due_date_time] }

但这是一个很慢的解决方案(ods表包含10k +条记录)。首选保存列以对数据库进行排序。如果不可能,请设置逻辑以在数据库查询中计算due_date_time