find_with_order 1.1.1 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
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