Class: ActiveScaffold::DataStructures::Sorting

Inherits:
Object
  • Object
show all
Includes:
OrmChecks, Enumerable
Defined in:
lib/active_scaffold/data_structures/sorting.rb

Overview

encapsulates the column sorting configuration for the List view

Constant Summary collapse

SORTING_STAGES =
%w[reset ASC DESC reset].each_cons(2).to_h.freeze
DEFAULT_SORTING_STAGES =
%w[ASC DESC ASC].each_cons(2).to_h.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from OrmChecks

active_record?, cast, #cast, column_type, columns, columns_hash, content_columns, default_value, mongoid?, quoted_table_name, reflect_on_all_associations, table_name, tableless?, type_for_attribute

Constructor Details

#initialize(columns, model) ⇒ Sorting

Returns a new instance of Sorting.



11
12
13
14
15
16
17
# File 'lib/active_scaffold/data_structures/sorting.rb', line 11

def initialize(columns, model)
  @columns = columns
  @clauses = []
  @constraint_columns = []
  @model = model
  @sorting_by_primary_key = false
end

Instance Attribute Details

#constraint_columnsObject

sorting_by_primary_key enabled by default for postgres



7
8
9
# File 'lib/active_scaffold/data_structures/sorting.rb', line 7

def constraint_columns
  @constraint_columns
end

#modelObject (readonly) Also known as: active_record_class

Returns the value of attribute model.



8
9
10
# File 'lib/active_scaffold/data_structures/sorting.rb', line 8

def model
  @model
end

#sorting_by_primary_keyObject

sorting_by_primary_key enabled by default for postgres



7
8
9
# File 'lib/active_scaffold/data_structures/sorting.rb', line 7

def sorting_by_primary_key
  @sorting_by_primary_key
end

Instance Method Details

#<<(arg) ⇒ Object

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



51
52
53
# File 'lib/active_scaffold/data_structures/sorting.rb', line 51

def <<(arg)
  add(*arg)
end

#add(column_name, direction = nil) ⇒ Object

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

Raises:

  • (ArgumentError)


39
40
41
42
43
44
45
46
47
48
# File 'lib/active_scaffold/data_structures/sorting.rb', line 39

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 %i[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(grouped_columns = nil) ⇒ Object

builds an order-by clause



127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# File 'lib/active_scaffold/data_structures/sorting.rb', line 127

def clause(grouped_columns = nil)
  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|
    next if constraint_columns.include? sort_column.name

    sql = grouped_columns ? grouped_columns[sort_column.name] : sort_column.sort[:sql]
    next if sql.blank?

    sql = sql.to_sql if sql.respond_to?(:to_sql)

    parts = Array(sql).map do |column|
      mongoid? ? [column, sort_direction] : "#{column} #{sort_direction}"
    end
    order << parts
  end

  order << @primary_key_order_clause if @sorting_by_primary_key && grouped_columns.nil?
  order.flatten!(1)
  order unless order.empty?
end

#clearObject

clears the sorting



75
76
77
78
# File 'lib/active_scaffold/data_structures/sorting.rb', line 75

def clear
  @default_sorting = false
  @clauses = []
end

#direction_of(column) ⇒ Object



85
86
87
88
89
90
# File 'lib/active_scaffold/data_structures/sorting.rb', line 85

def direction_of(column)
  clause = get_clause(column)
  return if clause.nil?

  clause[1]
end

#each(&block) ⇒ Object

iterate over the clauses



109
110
111
# File 'lib/active_scaffold/data_structures/sorting.rb', line 109

def each(&block)
  @clauses.each(&block)
end

#each_columnObject



113
114
115
# File 'lib/active_scaffold/data_structures/sorting.rb', line 113

def each_column
  @clauses.each { |clause| yield clause[0] }
end

#firstObject

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



118
119
120
# File 'lib/active_scaffold/data_structures/sorting.rb', line 118

def first
  @clauses.first
end

#next_sorting_of(column, sorted_by_default) ⇒ Object



94
95
96
97
# File 'lib/active_scaffold/data_structures/sorting.rb', line 94

def next_sorting_of(column, sorted_by_default)
  stages = sorted_by_default ? DEFAULT_SORTING_STAGES : SORTING_STAGES
  stages[direction_of(column)] || 'ASC'
end

#set(*args) ⇒ Object

clears the sorting before setting to the given column/direction set(column, direction) set(=> direction, column => direction) set(=> direction, => direction) set([column, direction], [column, direction])



60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/active_scaffold/data_structures/sorting.rb', line 60

def set(*args)
  # TODO: add deprecation unless args.size == 1 && args[0].is_a? Hash
  # when deprecation is removed:
  # * change list#sorting= to sorting.set(val)
  clear
  if args.first.is_a?(Enumerable)
    args.each do |h|
      h.is_a?(Hash) ? h.each { |c, d| add(c, d) } : add(*h)
    end
  else
    add(*args)
  end
end

#set_default_sortingObject



19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/active_scaffold/data_structures/sorting.rb', line 19

def set_default_sorting
  return unless active_record?

  # fallback to setting primary key ordering
  setup_primary_key_order_clause
  model_scope = model.send(:build_default_scope)
  order_clause = model_scope.order_values.join(',') if model_scope
  return unless order_clause

  # If an ORDER BY clause is found set default sorting according to it
  set_sorting_from_order_clause(order_clause, model.table_name)
  @default_sorting = true
end

#set_nested_sorting(table_name, order_clause) ⇒ Object



33
34
35
36
# File 'lib/active_scaffold/data_structures/sorting.rb', line 33

def set_nested_sorting(table_name, order_clause)
  clear
  set_sorting_from_order_clause(order_clause, table_name)
end

#sizeObject



122
123
124
# File 'lib/active_scaffold/data_structures/sorting.rb', line 122

def size
  @clauses.size
end

#sorts_by_method?Boolean

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

Returns:

  • (Boolean)


100
101
102
# File 'lib/active_scaffold/data_structures/sorting.rb', line 100

def sorts_by_method?
  @clauses.any? { |sorting| sorting[0].sort.is_a?(Hash) && sorting[0].sort.key?(:method) }
end

#sorts_by_sql?Boolean

Returns:

  • (Boolean)


104
105
106
# File 'lib/active_scaffold/data_structures/sorting.rb', line 104

def sorts_by_sql?
  @clauses.any? { |sorting| sorting[0].sort.is_a?(Hash) && sorting[0].sort.key?(:sql) }
end

#sorts_on?(column) ⇒ Boolean

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

Returns:

  • (Boolean)


81
82
83
# File 'lib/active_scaffold/data_structures/sorting.rb', line 81

def sorts_on?(column)
  !get_clause(column).nil?
end