class ActiveScaffold::DataStructures::Sorting

encapsulates the column sorting configuration for the List view

Public Class Methods

new(columns) click to toggle source
# File lib/active_scaffold/data_structures/sorting.rb, line 6
def initialize(columns)
  @columns = columns
  @clauses = []
end

Public Instance Methods

<<(arg) click to toggle source

an alias for add. must accept its arguments in a slightly different form, though.

# File lib/active_scaffold/data_structures/sorting.rb, line 42
def <<(arg)
  add(*arg)
end
add(column_name, direction = nil) click to toggle source

add a clause to the sorting, assuming the column is sortable

# File lib/active_scaffold/data_structures/sorting.rb, line 31
def add(column_name, direction = nil)
  direction ||= 'ASC'
  direction = direction.to_s.upcase
  column = get_column(column_name)
  raise ArgumentError, "Could not find column #{column_name}" if column.nil?
  raise ArgumentError, "Sorting direction unknown" unless [:ASC, :DESC].include? direction.to_sym
  @clauses << [column, direction] if column.sortable?
  raise ArgumentError, "Can't mix :method- and :sql-based sorting" if mixed_sorting?
end
clause() click to toggle source

builds an order-by clause

# File lib/active_scaffold/data_structures/sorting.rb, line 89
def clause
  return nil if sorts_by_method? || default_sorting?

  # unless the sorting is by method, create the sql string
  order = []
  each do |sort_column, sort_direction|
    sql = sort_column.sort[:sql]
    next if sql.nil? or sql.empty?

    order << "#{sql} #{sort_direction}"
  end

  order.join(', ') unless order.empty?
end
clear() click to toggle source

clears the sorting

# File lib/active_scaffold/data_structures/sorting.rb, line 53
def clear
  @default_sorting = false
  @clauses = []
end
direction_of(column) click to toggle source
# File lib/active_scaffold/data_structures/sorting.rb, line 63
def direction_of(column)
  clause = get_clause(column)
  return if clause.nil?
  clause[1]
end
each() { |clause| ... } click to toggle source

iterate over the clauses

# File lib/active_scaffold/data_structures/sorting.rb, line 79
def each
  @clauses.each { |clause| yield clause }
end
first() click to toggle source

provides quick access to the first (and sometimes only) clause

# File lib/active_scaffold/data_structures/sorting.rb, line 84
def first
  @clauses.first
end
set(*args) click to toggle source

clears the sorting before setting to the given column/direction

# File lib/active_scaffold/data_structures/sorting.rb, line 47
def set(*args)
  clear
  add(*args)
end
set_default_sorting(model) click to toggle source
# File lib/active_scaffold/data_structures/sorting.rb, line 11
def set_default_sorting(model)
  model_scope = model.send(:current_scoped_methods)
  order_clause = model_scope.arel.order_clauses.join(",") if model_scope

  # If an ORDER BY clause is found set default sorting according to it, else
  # fallback to setting primary key ordering
  if order_clause
    set_sorting_from_order_clause(order_clause, model.table_name)
    @default_sorting = true
  else
    set(model.primary_key, 'ASC') if model.column_names.include?(model.primary_key)
  end
end
set_nested_sorting(table_name, order_clause) click to toggle source
# File lib/active_scaffold/data_structures/sorting.rb, line 25
def set_nested_sorting(table_name, order_clause)
  clear
  set_sorting_from_order_clause(order_clause, table_name)
end
sorts_by_method?() click to toggle source

checks whether any column is configured to sort by method (using a proc)

# File lib/active_scaffold/data_structures/sorting.rb, line 70
def sorts_by_method?
  @clauses.any? { |sorting| sorting[0].sort.is_a? Hash and sorting[0].sort.has_key? :method }
end
sorts_by_sql?() click to toggle source
# File lib/active_scaffold/data_structures/sorting.rb, line 74
def sorts_by_sql?
  @clauses.any? { |sorting| sorting[0].sort.is_a? Hash and sorting[0].sort.has_key? :sql }
end
sorts_on?(column) click to toggle source

checks whether the given column (a Column object or a column name) is in the sorting

# File lib/active_scaffold/data_structures/sorting.rb, line 59
def sorts_on?(column)
  !get_clause(column).nil?
end

Protected Instance Methods

default_sorting?() click to toggle source
# File lib/active_scaffold/data_structures/sorting.rb, line 125
def default_sorting?
  @default_sorting
end
different_table?(model_table_name, order_table_name) click to toggle source
# File lib/active_scaffold/data_structures/sorting.rb, line 148
def different_table?(model_table_name, order_table_name)
  !order_table_name.nil? && model_table_name != order_table_name
end
extract_direction(direction_part) click to toggle source
# File lib/active_scaffold/data_structures/sorting.rb, line 160
def extract_direction(direction_part)
  if direction_part.to_s.upcase == 'DESC'
    'DESC'
  else
    'ASC'
  end
end
extract_order_parts(criterion_parts) click to toggle source
# File lib/active_scaffold/data_structures/sorting.rb, line 139
def extract_order_parts(criterion_parts)
  column_name_part, direction_part = criterion_parts.strip.split(' ')
  column_name_parts = column_name_part.split('.')
  order = {:direction => extract_direction(direction_part),
    :column_name => remove_quotes(column_name_parts.last)}
  order[:table_name] = remove_quotes(column_name_parts[-2]) if column_name_parts.length >= 2
  order
end
get_clause(column) click to toggle source

retrieves the sorting clause for the given column

# File lib/active_scaffold/data_structures/sorting.rb, line 107
def get_clause(column)
  column = get_column(column)
  @clauses.find{ |clause| clause[0] == column}
end
get_column(name_or_column) click to toggle source

possibly converts the given argument into a column object from @columns (if it’s not already)

# File lib/active_scaffold/data_structures/sorting.rb, line 113
def get_column(name_or_column)
  # it's a column
  return name_or_column if name_or_column.is_a? ActiveScaffold::DataStructures::Column
  # it's a name
  name_or_column = name_or_column.to_s.split('.').last if name_or_column.to_s.include? '.'
  return @columns[name_or_column]
end
mixed_sorting?() click to toggle source
# File lib/active_scaffold/data_structures/sorting.rb, line 121
def mixed_sorting?
  sorts_by_method? and sorts_by_sql?
end
remove_quotes(sql_name) click to toggle source
# File lib/active_scaffold/data_structures/sorting.rb, line 152
def remove_quotes(sql_name)
  if sql_name.starts_with?('"') || sql_name.starts_with?('`')
    sql_name[1, (sql_name.length - 2)]
  else
    sql_name
  end
end
set_sorting_from_order_clause(order_clause, model_table_name = nil) click to toggle source
# File lib/active_scaffold/data_structures/sorting.rb, line 129
def set_sorting_from_order_clause(order_clause, model_table_name = nil)
  clear
  order_clause.split(',').each do |criterion|
    unless criterion.blank?
      order_parts = extract_order_parts(criterion)
      add(order_parts[:column_name], order_parts[:direction]) unless different_table?(model_table_name, order_parts[:table_name])
    end
  end
end