activerecord-sort 6.1.0.1 → 6.1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/active_record/sort.rb +121 -1
- data/lib/active_record/sort/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5ee5bd719bed4e5e0588390935e7b237f58689dc469eab9a4940ee61117ca567
|
4
|
+
data.tar.gz: f3f6ea7df7d2d07d8f13acf20cc11bddcd6fa992bbb9572b378695ba6c18d628
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f6e95a89312f348f886a61b723d0f138947520e94cb58248b6eeff25cbfdca65d6bfdb34721ec661c2a9a8c6dfb9cc1e7be1cb1f195d7e57850a2a77d1475e60
|
7
|
+
data.tar.gz: 7ffe6b076093a14bdfd1b75f6863d5ac17e4bcdcaebf60c8233137637d4f100cb8e5dbaabd2176701db10f9262d2f52bcf7e8865f60c01e0e2be057515f85988
|
data/lib/active_record/sort.rb
CHANGED
@@ -1,6 +1,126 @@
|
|
1
1
|
require 'active_record'
|
2
|
+
require 'active_record/relation'
|
2
3
|
require 'arel/extensions'
|
3
4
|
|
4
|
-
|
5
|
+
module ActiveRecord
|
6
|
+
module Sort
|
5
7
|
|
8
|
+
# ordering:
|
9
|
+
# :id
|
10
|
+
# :name, :id
|
11
|
+
# :id => :desc
|
12
|
+
# :id => {:desc => :nulls_last}
|
13
|
+
# :listings => :id
|
14
|
+
# :listings => {:id => {:asc => :nulls_first}}
|
15
|
+
# :random
|
16
|
+
def sort(*ordering)
|
17
|
+
resource = all
|
18
|
+
ordering.compact!
|
19
|
+
ordering.flatten!
|
20
|
+
return resource if ordering.size == 0
|
21
|
+
|
22
|
+
ordering.each do |order|
|
23
|
+
order = Array(order)
|
24
|
+
|
25
|
+
order.each do |column_or_relation, options|
|
26
|
+
if column_or_relation.to_sym == :random
|
27
|
+
resource = resource.random_sort
|
28
|
+
elsif self.column_names.include?(column_or_relation.to_s)
|
29
|
+
resource = resource.sort_for_column(self.arel_table[column_or_relation.to_s], options)
|
30
|
+
elsif reflect_on_association(column_or_relation.to_sym)
|
31
|
+
resource = resource.select(resource.klass.arel_table[Arel::Nodes::SqlLiteral.new('*')])
|
32
|
+
resource = resource.sort_for_relation(column_or_relation.to_sym, options)
|
33
|
+
else
|
34
|
+
raise ActiveRecord::StatementInvalid.new("Unkown column #{column_or_relation}")
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
resource
|
40
|
+
end
|
41
|
+
|
42
|
+
def random_sort
|
43
|
+
self.order(Arel::Nodes::RandomOrdering.new)
|
44
|
+
end
|
45
|
+
|
46
|
+
# TODO: probably don't need to cast to sym
|
47
|
+
def sort_for_column(column, options)
|
48
|
+
direction = (options.is_a?(Hash) || options.class.name == "ActionController::Parameters" ? options.keys.first.to_sym : options.to_s.downcase.to_sym)
|
49
|
+
|
50
|
+
nulls = (options.is_a?(Hash) ? options.values.first.to_sym : nil)
|
51
|
+
if direction == :desc
|
52
|
+
self.order(Arel::Nodes::Descending.new(column, nulls))
|
53
|
+
elsif direction == :asc || direction == :''
|
54
|
+
self.order(Arel::Nodes::Ascending.new(column, nulls))
|
55
|
+
else
|
56
|
+
raise ActiveRecord::StatementInvalid.new("Unkown ordering #{direction}")
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def sort_for_relation(relation, options)
|
61
|
+
resource = self
|
62
|
+
relation = reflect_on_association(relation)
|
63
|
+
|
64
|
+
if relation.macro == :has_many
|
65
|
+
options = [options] if !options.is_a?(Array)
|
66
|
+
|
67
|
+
options.each do |order|
|
68
|
+
order = Array(order)
|
69
|
+
order.each do |column, options|
|
70
|
+
column = Arel::Attributes::Relation.new(relation.klass.arel_table[column], relation.name)
|
71
|
+
direction = (options.is_a?(Hash) ? options.keys.first.to_sym : options.to_s.downcase.to_sym)
|
72
|
+
|
73
|
+
nulls = (options.is_a?(Hash) ? options.values.first.to_sym : nil)
|
74
|
+
if direction == :desc
|
75
|
+
# aggregation = Arel::Nodes::Max.new([column], "max_#{relation.name}_#{column.name}")
|
76
|
+
# order = Arel::Nodes::Descending.new(Arel::Nodes::SqlLiteral.new("max_#{relation.name}_#{column.name}"), nulls)
|
77
|
+
|
78
|
+
if relation.options[:through]
|
79
|
+
resource = resource.joins(relation.options[:through] => relation.source_reflection_name)
|
80
|
+
else
|
81
|
+
resource = resource.joins(relation.name)
|
82
|
+
end
|
83
|
+
# resource = resource.select(aggregation)
|
84
|
+
# resource = resource.order(order)
|
85
|
+
resource = resource.order(Arel::Nodes::Descending.new(column, nulls))
|
86
|
+
else
|
87
|
+
# aggregation = Arel::Nodes::Min.new([column], "min_#{relation.name}_#{column.name}")
|
88
|
+
order = Arel::Nodes::Ascending.new(Arel::Nodes::SqlLiteral.new("min_#{relation.name}_#{column.name}"), nulls)
|
89
|
+
|
90
|
+
resource = resource.joins(relation.name)
|
91
|
+
# resource = resource.select(aggregation)
|
92
|
+
# resource = resource.order(order)
|
93
|
+
resource = resource.order(Arel::Nodes::Ascending.new(column, nulls))
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
elsif relation.macro == :belongs_to || relation.macro == :has_one
|
98
|
+
options = [options] if !options.is_a?(Array)
|
99
|
+
|
100
|
+
options.each do |order|
|
101
|
+
order = Array(order)
|
102
|
+
order.each do |column, options|
|
103
|
+
column = relation.klass.arel_table[column]
|
104
|
+
direction = (options.is_a?(Hash) ? options.keys.first.to_sym : options.to_s.downcase.to_sym)
|
105
|
+
|
106
|
+
nulls = (options.is_a?(Hash) ? options.values.first.to_sym : nil)
|
107
|
+
if direction == :asc
|
108
|
+
order = Arel::Nodes::Ascending.new(column, nulls)
|
109
|
+
else
|
110
|
+
order = Arel::Nodes::Descending.new(column, nulls)
|
111
|
+
end
|
112
|
+
|
113
|
+
resource = resource.left_outer_joins(relation.name)
|
114
|
+
resource = resource.order(order)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
resource
|
120
|
+
end
|
121
|
+
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
ActiveRecord::QueryMethods.prepend(ActiveRecord::Sort)
|
6
126
|
ActiveRecord::Querying.delegate :sort, to: :all
|