hightop 0.2.1 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7bfda8167d2141d8bd0be9678f1f285fe8417d0deecac5a04cee44f50efcf876
4
- data.tar.gz: 0414c92e5702679fc169dbecb03d754e79461968e97a39cd2cca15d94ec4daa3
3
+ metadata.gz: 3e2fc0f11b1504620f8989548410fb965f5399f10a2a160f8911c72e1ee9be73
4
+ data.tar.gz: b9a4289ebbd844162263c513bfcc93ebcb1a7c97f27b7ec8bee511729d7b0d37
5
5
  SHA512:
6
- metadata.gz: baad6fa1e6f4f404fd2f33448a971412ea9bf50257f5dd69531e341aa0a3afb69c816ac3191a9988ed8f30b19cce2c1d0837fb077e78fe589a7975b0283ec6d7
7
- data.tar.gz: a66db10388aff6057d63f9ae977a700c0065d222a52dd04df0e7ea4bbd87f5ee51a145ff875aea5b9042dbbbaff2a10543f612519b3c65ec525852728aef5f82
6
+ metadata.gz: 4bb15ebfacc0e6383ca32f46cca4839d8f8a69180154ddf2a6a9fca65b5fe11cfbdcf087b3ec767d21fabfa75db197c4b7b1d1f68bd332e030076f1ea5c8f0e2
7
+ data.tar.gz: 5659dc207fb18a98d70febfbd51f28a5155672365ed9b9a8e06dceff27d0c640abbb99461c1410f6209571f4e283201724383d82fd732c7ddab49cbcc665a66d
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## 0.2.2
2
+
3
+ - Added support for Mongoid
4
+
1
5
  ## 0.2.1
2
6
 
3
7
  - Added support for arrays and hashes
data/README.md CHANGED
@@ -4,23 +4,16 @@ A nice shortcut for group count queries
4
4
 
5
5
  ```ruby
6
6
  Visit.top(:browser)
7
+ # {
8
+ # "Chrome" => 63,
9
+ # "Safari" => 50,
10
+ # "Firefox" => 34
11
+ # }
7
12
  ```
8
13
 
9
- instead of
14
+ Works with Active Record, Mongoid, arrays and hashes
10
15
 
11
- ```ruby
12
- Visit.group(:browser).where("browser IS NOT NULL").order("count_all DESC, browser").count
13
- ```
14
-
15
- Be sure to [sanitize user input](https://rails-sqli.org/) like you must with `group`
16
-
17
- Also works with arrays and hashes
18
-
19
- ```ruby
20
- ["up", "up", "down"].top(1)
21
- ```
22
-
23
- [![Build Status](https://travis-ci.org/ankane/hightop.svg)](https://travis-ci.org/ankane/hightop)
16
+ [![Build Status](https://travis-ci.org/ankane/hightop.svg?branch=master)](https://travis-ci.org/ankane/hightop)
24
17
 
25
18
  ## Installation
26
19
 
@@ -68,6 +61,19 @@ And min count
68
61
  Visit.top(:city, min: 10)
69
62
  ```
70
63
 
64
+ ## User Input
65
+
66
+ If passing user input as the column, be sure to sanitize it first [like you must](https://rails-sqli.org/) with `group`.
67
+
68
+ ```ruby
69
+ column = params[:column]
70
+
71
+ # check against permitted columns
72
+ raise "Unpermitted column" unless ["column_a", "column_b"].include?(column)
73
+
74
+ User.top(column)
75
+ ```
76
+
71
77
  ## Arrays and Hashes
72
78
 
73
79
  Arrays
data/lib/hightop.rb CHANGED
@@ -3,9 +3,14 @@ require "active_support"
3
3
 
4
4
  # modules
5
5
  require "hightop/enumerable"
6
- require "hightop/kicks"
7
6
  require "hightop/version"
8
7
 
9
8
  ActiveSupport.on_load(:active_record) do
9
+ require "hightop/kicks"
10
10
  extend Hightop::Kicks
11
11
  end
12
+
13
+ ActiveSupport.on_load(:mongoid) do
14
+ require "hightop/mongoid"
15
+ Mongoid::Document::ClassMethods.include(Hightop::Mongoid)
16
+ end
@@ -1,6 +1,6 @@
1
1
  module Enumerable
2
2
  def top(*args, &block)
3
- if block || !respond_to?(:scoping)
3
+ if block || !(respond_to?(:scoping) || respond_to?(:with_scope))
4
4
  limit, options, _ = args
5
5
  if limit.is_a?(Hash) && args.size == 1
6
6
  options = limit
@@ -19,8 +19,10 @@ module Enumerable
19
19
  arr = counts.sort_by { |_, v| -v }
20
20
  arr = arr[0...limit] if limit
21
21
  Hash[arr]
22
- else
22
+ elsif respond_to?(:scoping)
23
23
  scoping { @klass.send(:top, *args, &block) }
24
+ else
25
+ with_scope(self) { klass.send(:top, *args, &block) }
24
26
  end
25
27
  end
26
28
  end
@@ -0,0 +1,52 @@
1
+ module Hightop
2
+ module Mongoid
3
+ # super helpful article
4
+ # https://maximomussini.com/posts/mongoid-aggregation-dsl/
5
+ def top(column, limit = nil, distinct: nil, uniq: nil, min: nil, nil: nil)
6
+ distinct ||= uniq
7
+
8
+ relation = all
9
+
10
+ # terribly named option
11
+ unless binding.local_variable_get(:nil)
12
+ (column.is_a?(Array) ? column : [column]).each do |c|
13
+ relation = relation.and(c.ne => nil)
14
+ end
15
+ end
16
+
17
+ ids = {}
18
+ Array(column).each_with_index do |c, i|
19
+ ids["c#{i}"] = "$#{c}"
20
+ end
21
+
22
+ if distinct
23
+ # group with distinct column first, then group without it
24
+ # https://stackoverflow.com/questions/24761266/select-group-by-count-and-distinct-count-in-same-mongodb-query/24770233#24770233
25
+ distinct_ids = ids.merge("c#{ids.size}" => "$#{distinct}")
26
+ relation = relation.group(_id: distinct_ids, count: {"$sum" => 1})
27
+ ids.each_key do |k|
28
+ ids[k] = "$_id.#{k}"
29
+ end
30
+ end
31
+
32
+ relation = relation.group(_id: ids, count: {"$sum" => 1})
33
+
34
+ if min
35
+ relation.pipeline.push("$match" => {"count" => {"$gte" => min}})
36
+ end
37
+
38
+ relation = relation.desc(:count)
39
+ if limit
40
+ relation = relation.limit(limit)
41
+ end
42
+
43
+ result = {}
44
+ collection.aggregate(relation.pipeline).each do |doc|
45
+ key = doc["_id"].values
46
+ key = key[0] if key.size == 1
47
+ result[key] = doc["count"]
48
+ end
49
+ result
50
+ end
51
+ end
52
+ end
@@ -1,3 +1,3 @@
1
1
  module Hightop
2
- VERSION = "0.2.1"
2
+ VERSION = "0.2.2"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hightop
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kane
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-08-05 00:00:00.000000000 Z
11
+ date: 2019-08-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -92,6 +92,7 @@ files:
92
92
  - lib/hightop.rb
93
93
  - lib/hightop/enumerable.rb
94
94
  - lib/hightop/kicks.rb
95
+ - lib/hightop/mongoid.rb
95
96
  - lib/hightop/version.rb
96
97
  homepage: https://github.com/ankane/hightop
97
98
  licenses: