Oasist Blog

This blog mainly features Natural Languages, Programming and Life Hacks.

Implement Sorting without Ransack

f:id:oasist:20200614004721p:plain
Ruby on Rails

目次

1. Environment

2. Requirements

  • Sort data by 学生コード (student_code), 学生名 (name), 学年 (grade_id) in students table
  • Sustain the search result
  • Properly partialise the function to apply to other pages in the future

3. Custom Helper

3-1. StudentHelper

Implement custom helpers for each model.

module StudentHelper
  def student_sort_link(column)
    search_params = search_students_params.empty? ? {} : { search_students_form: search_students_params }
    sort_link(Student.human_attribute_name(column), column, search_params)
  end
end
  • Take column as argument
  • Return an empty hash if search form parameter is empty or return a hash including key and value of the search result
  • Pass column to the common method sort_link
    • 1st argument: String with a link for sorting localised in Japanese
    • 2nd argument: Generate a query string column=[column]
    • 3rd argument: A hash of key and velue of search from parameter

3-2. ApplicationHelper

Implement a common procedure.

module ApplicationHelper
  def sort_link(column_name, column, **additional_params)
    if params[:column] != column.to_s || params[:direction].nil?
      link_to column_name, { column: column, direction: :asc, **additional_params }
    elsif params[:column] == column.to_s && params[:direction] == 'asc'
      link_to "#{column_name}", { column: column, direction: :desc, **additional_params }
    elsif params[:column] == column.to_s && params[:direction] == 'desc'
      link_to "#{column_name}", { column: column, direction: :asc, **additional_params }
    end
  end
end
  • Receive the search result in 3rd argument as a varibale one
  • Here are three conditions
    • The sorted column is not equal to the one you try to sort, or no column is sorted
      • => Sort the column in asc
    • The sorted column is equal to the one you try to sort, and the column is sorted in asc
      • => Sort the column in desc and appears
    • The sorted column is equal to the one you try to sort, and the column is sorted in desc
      • => Sort the column in asc and appears

4. Controller

Run SQL with the query string.

def index
  @students = Student.search(@search_form).order(sort_column => sort_direction).preload(:grade)
end

.
.
.

private

def sort_column
  params[:column].in?(%w(student_code name grade_id)) ? params[:column] : :id
end

def sort_direction
  params[:direction].in?(%w(asc desc)) ? params[:direction] : :asc
end
  • order receives column to sort => asc/desc as a hash
  • sort_column: If the colomn exists in the white list, it is assigned to key of order. If not, id is allotted.
  • sort_direction: If the sorting direction in the white list, it is assigned to value of order. If not, asc is allotted.

5. View

Take symbols as arugument as follows.

<th class="col-sm-2"><%= student_sort_link(:user_code) %></th>
<th class="col-sm-3"><%= student_sort_link(:name) %></th>
<th class="col-sm-2"><%= student_sort_link(:grade_id) %></th>

6. Sort by student_code

  • Default: No query string

f:id:oasist:20200614004949p:plain
No query string


  • ASC: ?column=user_code&direction=asc

f:id:oasist:20200614005018p:plain
?column=user_code&direction=asc`


  • DESC: ?column=user_code&direction=desc

f:id:oasist:20200614005041p:plain
?column=user_code&direction=desc`