find_with_order 1.1.1 → 1.2.0
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/README.md +11 -0
- data/lib/find_with_order.rb +17 -6
- data/lib/find_with_order/mysql_support.rb +14 -6
- data/lib/find_with_order/pg_support.rb +14 -9
- data/lib/find_with_order/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 3024d02ad143449be88b240808017c7ab38500b3
|
|
4
|
+
data.tar.gz: d65519466c2eee4e8cd41e3d887d8368c5af9e67
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 26c9c3b58f458a24bd87c90d4caa869aa9c09f28f26dd1409dd22a877b105f2aab24f413dc95d09931bc064aa89e9e97f1074d0839f2569934972187c36aed50
|
|
7
|
+
data.tar.gz: 9d16130c3d37aa9f69eaabd2e61684392cca820a7708bc75a0d9043a24cca3e382c70211385d8618e5e2acd60cad5e7c56e3b97b4ba7b1e5f7a3147b090eafa2
|
data/README.md
CHANGED
|
@@ -35,6 +35,7 @@ User.find([3, 1, 5]).map(&:id)
|
|
|
35
35
|
User.find_with_order([3, 1, 5]).map(&:id)
|
|
36
36
|
# => [3, 1, 5]
|
|
37
37
|
```
|
|
38
|
+
|
|
38
39
|
### Support order other columns
|
|
39
40
|
```rb
|
|
40
41
|
User.where(name: %w(Pearl John Kathenrie)).pluck(:name)
|
|
@@ -44,6 +45,16 @@ User.where_with_order(:name, %w(Pearl John Kathenrie)).pluck(:name)
|
|
|
44
45
|
# => ['Pearl', 'John', 'Kathenrie']
|
|
45
46
|
```
|
|
46
47
|
|
|
48
|
+
### Just order part of results
|
|
49
|
+
```rb
|
|
50
|
+
User.where(leader: true).with_order(:name, %w(Pearl John)).pluck(:name)
|
|
51
|
+
# => ['Pearl', 'John', 'Kathenrie']
|
|
52
|
+
|
|
53
|
+
User.where(leader: true).with_order(:name, %w(Pearl John), null_first: true).pluck(:name)
|
|
54
|
+
# => ['Kathenrie', 'Pearl', 'John']
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
|
|
47
58
|
## Benchmark
|
|
48
59
|
### Compare with manually sorting in rails
|
|
49
60
|
|
data/lib/find_with_order.rb
CHANGED
|
@@ -3,20 +3,31 @@ require "find_with_order/mysql_support"
|
|
|
3
3
|
require "find_with_order/pg_support"
|
|
4
4
|
require 'active_record'
|
|
5
5
|
|
|
6
|
+
module FindWithOrder
|
|
7
|
+
class << self
|
|
8
|
+
def supporter
|
|
9
|
+
return FindWithOrder::PGSupport if defined?(PG)
|
|
10
|
+
return FindWithOrder::MysqlSupport
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
6
15
|
class << ActiveRecord::Base
|
|
7
16
|
def find_with_order(ids)
|
|
8
17
|
return none if ids.blank?
|
|
9
|
-
|
|
10
|
-
return FindWithOrder::PGSupport.find_with_order(self, ids) if defined?(PG)
|
|
11
|
-
return FindWithOrder::MysqlSupport.find_with_order(self, ids)
|
|
18
|
+
return FindWithOrder.supporter.find_with_order(self, ids.uniq)
|
|
12
19
|
end
|
|
20
|
+
|
|
13
21
|
def where_with_order(column, ids)
|
|
14
22
|
return none if ids.blank?
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
23
|
+
return FindWithOrder.supporter.where_with_order(self, column, ids.uniq)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def with_order(column, ids, null_first: false)
|
|
27
|
+
FindWithOrder.supporter.with_order(self, column, ids, null_first: null_first)
|
|
18
28
|
end
|
|
19
29
|
end
|
|
30
|
+
|
|
20
31
|
unless ActiveRecord::Base.respond_to?(:none) # extend only if not implement yet
|
|
21
32
|
class ActiveRecord::Base
|
|
22
33
|
def self.none #For Rails 3
|
|
@@ -1,10 +1,18 @@
|
|
|
1
|
-
module FindWithOrder
|
|
2
|
-
|
|
3
|
-
def
|
|
4
|
-
|
|
1
|
+
module FindWithOrder::MysqlSupport
|
|
2
|
+
class << self
|
|
3
|
+
def find_with_order(relation, ids)
|
|
4
|
+
relation.where(id: ids)
|
|
5
|
+
.order("field(#{relation.table_name}.id, #{ids.join(',')})")
|
|
6
|
+
.to_a
|
|
5
7
|
end
|
|
6
|
-
|
|
7
|
-
|
|
8
|
+
|
|
9
|
+
def where_with_order(relation, column, ids)
|
|
10
|
+
with_order(relation.where(column => ids), column, ids, null_first: true)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def with_order(relation, column, ids, null_first: false)
|
|
14
|
+
return relation.order("field(#{column}, #{ids.map(&:inspect).join(',')})") if null_first
|
|
15
|
+
return relation.order("field(#{column}, #{ids.reverse.map(&:inspect).join(',')}) DESC")
|
|
8
16
|
end
|
|
9
17
|
end
|
|
10
18
|
end
|
|
@@ -1,26 +1,31 @@
|
|
|
1
|
-
module FindWithOrder
|
|
2
|
-
|
|
3
|
-
def
|
|
1
|
+
module FindWithOrder::PGSupport
|
|
2
|
+
class << self
|
|
3
|
+
def find_with_order(relation, ids)
|
|
4
4
|
# return relation.where(id: ids).order("array_position(ARRAY[#{ids.join(',')}], #{relation.table_name}.id)").to_a #array_position is only support in PG >= 9.5
|
|
5
5
|
return relation.where(id: ids)
|
|
6
6
|
.joins("JOIN (SELECT id.val, row_number() over() FROM (VALUES(#{ids.join('),(')})) AS id(val)) AS id ON (#{relation.table_name}.id = id.val)")
|
|
7
7
|
.order('row_number')
|
|
8
8
|
end
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
|
|
10
|
+
def where_with_order(relation, column, ids)
|
|
11
|
+
with_order(relation.where(column => ids), column, ids)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def with_order(relation, column, ids, null_first: false)
|
|
15
|
+
ids = ids.reverse if null_first
|
|
11
16
|
case ids.first
|
|
12
17
|
when Numeric
|
|
18
|
+
values = ids.join('),(')
|
|
13
19
|
# return relation.order("array_position(ARRAY[#{ids.join(',')}], #{column})") #array_position is only support in PG >= 9.5
|
|
14
|
-
return relation.joins("JOIN (SELECT id.val, row_number() over() FROM (VALUES(#{ids.join('),(')})) AS id(val)) AS id ON (#{column} = id.val)")
|
|
15
|
-
.order('row_number')
|
|
16
20
|
when String
|
|
17
21
|
ids.map!{|s| ActiveRecord::Base.connection.quote_string(s) }
|
|
22
|
+
values = "'#{ids.join("'),('")}'"
|
|
18
23
|
# return relation.order("array_position(ARRAY['#{ids.join("','")}']::varchar[], #{column})") #array_position is only support in PG >= 9.5
|
|
19
|
-
return relation.joins("JOIN (SELECT id.val, row_number() over() FROM (VALUES('#{ids.join("'),('")}')) AS id(val)) AS id ON (#{column} = id.val)")
|
|
20
|
-
.order('row_number')
|
|
21
24
|
else
|
|
22
25
|
raise "not support type: #{ids.first.class}"
|
|
23
26
|
end
|
|
27
|
+
return relation.joins("LEFT JOIN (SELECT id.val, row_number() over() FROM (VALUES(#{values})) AS id(val)) AS id ON (#{column} = id.val)")
|
|
28
|
+
.order(null_first ? 'row_number DESC' : 'row_number')
|
|
24
29
|
end
|
|
25
30
|
end
|
|
26
31
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: find_with_order
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- khiav reoy
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2017-
|
|
11
|
+
date: 2017-07-02 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|