Sorting a result defined by remote parameters

100 Views Asked by At

i have this index action:

  def index
    limit = params[:limit]
    page = params[:page]
    sort = params[:sort].split(',')
    @term = nil
    if params[:search]
      @term = params[:search]
      @lessons = policy_scope(Lesson).search(@term)
                                     .order("#{sort[0]} #{sort[1].upcase}")
                                     .paginate(page: page, per_page: limit)
    else
      @lessons = policy_scope(Lesson).order("#{sort[0]} #{sort[1].upcase}")
                                     .paginate(page: page, per_page: limit)
    end
  end

which is fed by a vuejs frontend with a vuetify datatable and its purpose is to send out an array of lesson objects, filtered and sorted by the frontend.

this works pretty good with default rails..

however, with the mobility gem involved there is no fieldname "title" for example or "title_en", so the order stops working. in mobility you have some "fake column names" and it automagically handles it to search for the value in a key-value table ( https://github.com/shioyama/mobility#getting-started )

so i sat me down and fired up the console and figured out that:

  1. .order(title: :desc) - works
  2. .order(title_en: :asc) - works
  3. everything with strings involved, like .order('title DESC') or .order('title_en ASC') does not work and results in an error like

ActionView::Template::Error (PG::UndefinedColumn: ERROR: column "title_en" does not exist LINE 1: SELECT "lessons".* FROM "lessons" ORDER BY title_en ASC LIMI...

is there a way i could get this working? maybe there is something to generate title: out of 'title'? Or some other magic?

thanks!

1

There are 1 best solutions below

2
On

You can call the order method like this instead:

.order(sort[0] => sort[1])

Passing "a" => "b" to a method is the same as passing "a": "b".