Search code examples
rubysequel

Dynamic Sort Order in Sequel


We want to sort a database dynamically. The sorting sequence is stored in a ruby hash -

sortorder = [
  {
    'property'  => 'company',
    'direction' => 'asc'
  },
  {
    'property'  => 'name',
    'direction' => 'asc'
  },
  {
    'property'  => 'id',
    'direction' => 'desc'
  }
]

We are trying to build the query like this -

query = DB[:contacts]
sortorder.each do |s|
  column = s['property']
  direction = s['direction'].downcase

  if direction == 'asc'
    query = query.order_append(column.to_sym)
  else
    query = query.order_append(column.to_sym).reverse
  end
end

However, the query appears like this

#<Sequel::SQLite::Dataset: "SELECT * FROM `contacts` ORDER BY `company` DESC, `name` DESC, `id` DESC">

That is, all the columns get sorted in 'descending' order (the last 'direction' given)

How do we ensure the query matches the hash given? Also, if this can be done in a better way it'll be very, very helpful.


Solution

  • reverse is reversing all orders. You have to pass the direction for each order:

    query = DB[:contacts]
    sortorder.each do |s|
      column = s['property']
      direction = s['direction'].downcase
    
      query = query.order_append(column.to_sym.send(direction.to_sym))
    end