class ActiveScaffold::DataStructures::Sorting

encapsulates the column sorting configuration for the List view

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 41
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, "Sorting direction unknown" unless [:ASC, :DESC].include? direction.to_sym
  @clauses << [column, direction.untaint] if column and 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 88
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 << Array(sql).map {|column| "#{column} #{sort_direction}"}.join(', ')
  end

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

clears the sorting

# File lib/active_scaffold/data_structures/sorting.rb, line 52
def clear
  @default_sorting = false
  @clauses = []
end
direction_of(column) click to toggle source
# File lib/active_scaffold/data_structures/sorting.rb, line 62
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 78
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 83
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 46
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(:build_default_scope)
  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 69
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 73
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 58
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 124
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 147
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 159
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 138
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 106
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 112
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 120
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 151
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 128
def set_sorting_from_order_clause(order_clause, model_table_name = nil)
  clear
  order_clause.to_s.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

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