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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d955f79fc86d2b1d9ddd2e4b0e5576fb2d89d252
4
- data.tar.gz: d0eb726b23436e935c67065ec57ba4423fac9657
3
+ metadata.gz: 3024d02ad143449be88b240808017c7ab38500b3
4
+ data.tar.gz: d65519466c2eee4e8cd41e3d887d8368c5af9e67
5
5
  SHA512:
6
- metadata.gz: 8abb85b303feae5550fafad62a2db381c16350829427f4ce46da796e3a15fcc0e28fa2cf25b3b168407ebe81cb98280fab6a584dc91ebe4214ed4bad6cab949a
7
- data.tar.gz: 33ad5f2bd2f4957828d02072ca4c4feca2b35c39d8c85021e3820cc8fb9882a540f5ee306d74c392ead5fca7ce954886355af12ebacd2a20d0813d2efde39e04
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
 
@@ -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
- ids = ids.uniq
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
- ids = ids.uniq
16
- return FindWithOrder::PGSupport.where_with_order(self, column, ids) if defined?(PG)
17
- return FindWithOrder::MysqlSupport.where_with_order(self, column, ids)
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
- module MysqlSupport
3
- def self.find_with_order(relation, ids)
4
- return relation.where(id: ids).order("field(#{relation.table_name}.id, #{ids.join(',')})").to_a
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
- def self.where_with_order(relation, column, ids)
7
- return relation.where(column => ids).order("field(#{column}, #{ids.map(&:inspect).join(',')})")
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
- module PGSupport
3
- def self.find_with_order(relation, ids)
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
- def self.where_with_order(relation, column, ids)
10
- relation = relation.where(column => ids)
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
@@ -1,3 +1,3 @@
1
1
  module FindWithOrder
2
- VERSION = "1.1.1"
2
+ VERSION = "1.2.0"
3
3
  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.1.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-06-22 00:00:00.000000000 Z
11
+ date: 2017-07-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler