daveanderson88
daveanderson88

Reputation: 347

Ordering a collection by instance method

I would like to order a collection first by priority and then due time like this:

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

The problem is due_date_time is an instance method of Od, so I get

PG::UndefinedColumn: ERROR: column ods.due_date_time does not exist

I have tried the following, but it seems that by sorting and mapping ids, then finding them again with .where means the sort order is lost.

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

due_date_time calls a method from a child association:

  def due_date_time
    run.cut_off_time
  end

run.cut_off_time is defined here:

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

I'm sure there is an easier way. Any help much appreciated! Thanks.

Upvotes: 2

Views: 900

Answers (1)

Leo
Leo

Reputation: 1773

order from ActiveRecord similar to sort from ruby. So, Od.all.sort run iteration after the database query Od.all, run a new iteration map and then send a new database query. Also Od.all.sort has no sense because where select record when id included in ids but not searching a record for each id.

Easier do something like this:

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

But that is a slow solution(ods table include 10k+ records). Prefer to save column to sort to the database. When that is not possible set logic to calculate due_date_time in a database query.

Upvotes: 1

Related Questions