ransack_mongo 0.0.1 → 0.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/.travis.yml +16 -0
- data/README.md +63 -4
- data/lib/ransack_mongo/mongo_adapter.rb +20 -13
- data/lib/ransack_mongo/query.rb +12 -2
- data/lib/ransack_mongo/version.rb +1 -1
- data/ransack_mongo.gemspec +2 -3
- data/spec/ransack_mongo/mongo_adapter_spec.rb +25 -22
- data/spec/ransack_mongo/query_spec.rb +13 -4
- data/spec/spec_helper.rb +0 -1
- metadata +6 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 653de3c263786edc9d472e925e4c2802b9d8723e
|
4
|
+
data.tar.gz: 6bc873650e072552a2582dca3fdc4f3a6606c5d0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: add84c5b3298b51116656d07c7d541fa6733a1b0dc568caf6a15297921edc2342042a32408dfb797b526ddb8a80c9b2e246106a5ae9f028109e6d5a404303edf
|
7
|
+
data.tar.gz: 23e2806cc27103853ccf12a53d224ac93cc319c47f09e675556493e140947f4f3e91914fabf864c4f49eb4d553dd34328aa8904b759553fa1799088796f4661c
|
data/.travis.yml
ADDED
data/README.md
CHANGED
@@ -1,6 +1,14 @@
|
|
1
|
-
#
|
1
|
+
# Ransack Mongo
|
2
2
|
|
3
|
-
|
3
|
+
[](https://travis-ci.org/phstc/ransack_mongo)
|
4
|
+
|
5
|
+
Ransack Mongo is based on [Ransack](https://github.com/activerecord-hackery/ransack), but for MongoDB.
|
6
|
+
|
7
|
+
With Ransack Mongo you can convert query params into Mongo queries.
|
8
|
+
|
9
|
+
## Why another gem?
|
10
|
+
|
11
|
+
> [Given that Ransack is built on top of ARel and that ARel only works with relational databases, I don't see how we could add Mongoid support without dramatically changing everything.](https://github.com/activerecord-hackery/ransack/issues/120#issuecomment-7539851)
|
4
12
|
|
5
13
|
## Installation
|
6
14
|
|
@@ -18,11 +26,62 @@ Or install it yourself as:
|
|
18
26
|
|
19
27
|
## Usage
|
20
28
|
|
21
|
-
|
29
|
+
```ruby
|
30
|
+
# GET /customers?q[name_eq]=Pablo&q[middle_name_or_last_name_cont]=Cantero
|
31
|
+
# params[:q]
|
32
|
+
# => { name_eq: 'Pablo', middle_name_or_last_name_cont: 'Cantero' }
|
33
|
+
# query.to_query(params[:q])
|
34
|
+
# => { name: 'Pablo', '$or' => { middle_name: /Cantero/i, last_name: /Cantero/i } }
|
35
|
+
|
36
|
+
# GET /customers
|
37
|
+
def index
|
38
|
+
query = RansackMongo::Query.new
|
39
|
+
selector = query.to_query(params[:q])
|
40
|
+
|
41
|
+
# Mongo Ruby Driver
|
42
|
+
@customers = db.customers.find(selector)
|
43
|
+
|
44
|
+
# Mongoid
|
45
|
+
@customers = Customer.where(selector)
|
46
|
+
end
|
47
|
+
```
|
48
|
+
|
49
|
+
### Available predicates
|
50
|
+
|
51
|
+
* eq
|
52
|
+
* not_eq
|
53
|
+
* cont
|
54
|
+
* in
|
55
|
+
* gt
|
56
|
+
* lt
|
57
|
+
* gteq
|
58
|
+
* lteq
|
59
|
+
|
60
|
+
### OR operator
|
61
|
+
|
62
|
+
You can also combine predicates for OR queries.
|
63
|
+
|
64
|
+
```ruby
|
65
|
+
query_param = { name_eq: 'Pablo', middle_name_or_last_name_cont: 'Cantero' }
|
66
|
+
query.to_query(params[:q])
|
67
|
+
# => { name: 'Pablo', '$or' => { middle_name: /Cantero/i, last_name: /Cantero/i } }
|
68
|
+
```
|
69
|
+
|
70
|
+
### to_query!
|
71
|
+
|
72
|
+
You can use to_query! for stricter validations. This method will raise an exception if a query cannot be produced.
|
73
|
+
```ruby
|
74
|
+
# xpto isn't a valid predicate
|
75
|
+
|
76
|
+
query.to_query(name_xpto: 'Pablo')
|
77
|
+
# => {}
|
78
|
+
query.to_query!(name_xpto: 'Pablo')
|
79
|
+
# => RansackMongo::MatcherNotFound: No matchers found. To allow empty queries use .to_query instead
|
80
|
+
```
|
22
81
|
|
23
82
|
## Contributing
|
24
83
|
|
25
|
-
1. Fork it (
|
84
|
+
1. Fork it ( https://github.com/phstc/ransack_mongo/fork )
|
26
85
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
27
86
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
28
87
|
4. Push to the branch (`git push origin my-new-feature`)
|
@@ -27,23 +27,19 @@ module RansackMongo
|
|
27
27
|
end
|
28
28
|
|
29
29
|
def gt_matcher(attr, value)
|
30
|
-
|
31
|
-
@query[attr]['$gt'] = value.to_f
|
30
|
+
append_sizeable_matcher('$gt', attr, value)
|
32
31
|
end
|
33
32
|
|
34
33
|
def lt_matcher(attr, value)
|
35
|
-
|
36
|
-
@query[attr]['$lt'] = value.to_f
|
34
|
+
append_sizeable_matcher('$lt', attr, value)
|
37
35
|
end
|
38
36
|
|
39
37
|
def gteq_matcher(attr, value)
|
40
|
-
|
41
|
-
@query[attr]['$gte'] = value.to_f
|
38
|
+
append_sizeable_matcher('$gte', attr, value)
|
42
39
|
end
|
43
40
|
|
44
41
|
def lteq_matcher(attr, value)
|
45
|
-
|
46
|
-
@query[attr]['$lte'] = value.to_f
|
42
|
+
append_sizeable_matcher('$lte', attr, value)
|
47
43
|
end
|
48
44
|
|
49
45
|
def or_op # or operation
|
@@ -60,13 +56,24 @@ module RansackMongo
|
|
60
56
|
@query = original_query
|
61
57
|
end
|
62
58
|
|
63
|
-
def sanitize(unsanitized)
|
64
|
-
# http://docs.mongodb.org/manual/faq/developers/#how-does-mongodb-address-sql-or-query-injection
|
65
|
-
unsanitized
|
66
|
-
end
|
67
|
-
|
68
59
|
def self.predicates
|
69
60
|
PREDICATES
|
70
61
|
end
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
def append_sizeable_matcher(m, attr, value)
|
66
|
+
@query[attr] ||= {}
|
67
|
+
@query[attr][m] = parse_sizeable_value(value)
|
68
|
+
end
|
69
|
+
|
70
|
+
def parse_sizeable_value(value)
|
71
|
+
case value
|
72
|
+
when Date, Time
|
73
|
+
value
|
74
|
+
else
|
75
|
+
Float(value) rescue value
|
76
|
+
end
|
77
|
+
end
|
71
78
|
end
|
72
79
|
end
|
data/lib/ransack_mongo/query.rb
CHANGED
@@ -14,8 +14,8 @@ module RansackMongo
|
|
14
14
|
|
15
15
|
parsed_predicates.keys.each do |p|
|
16
16
|
parsed_predicates[p].each do |parsed_predicate|
|
17
|
-
attr =
|
18
|
-
value =
|
17
|
+
attr = parsed_predicate['attr']
|
18
|
+
value = parsed_predicate['value']
|
19
19
|
|
20
20
|
begin
|
21
21
|
if attr.include? '_or_'
|
@@ -34,6 +34,16 @@ module RansackMongo
|
|
34
34
|
db_adapter.to_query
|
35
35
|
end
|
36
36
|
|
37
|
+
def to_query!(params)
|
38
|
+
selector = to_query params
|
39
|
+
|
40
|
+
if selector.empty?
|
41
|
+
raise MatcherNotFound, "No matchers found. To allow empty queries use .to_query instead"
|
42
|
+
end
|
43
|
+
|
44
|
+
selector
|
45
|
+
end
|
46
|
+
|
37
47
|
def or_query(db_adapter, attr, value, p)
|
38
48
|
db_adapter.or_op do
|
39
49
|
attr.split('_or_').each do |or_attr|
|
data/ransack_mongo.gemspec
CHANGED
@@ -9,9 +9,8 @@ Gem::Specification.new do |spec|
|
|
9
9
|
spec.authors = ['Pablo Cantero']
|
10
10
|
spec.email = ['pablo@pablocantero.com']
|
11
11
|
spec.homepage = 'https://github.com/phstc/ransack_mongo'
|
12
|
-
spec.summary = %q{
|
13
|
-
spec.description = %q{Ransack Mongo is
|
14
|
-
spec.homepage = ''
|
12
|
+
spec.summary = %q{Query params based searching for MongoDB}
|
13
|
+
spec.description = %q{Ransack Mongo is based on Ransack but for MongoDB}
|
15
14
|
spec.license = 'MIT'
|
16
15
|
|
17
16
|
spec.files = `git ls-files`.split($/)
|
@@ -48,35 +48,38 @@ module RansackMongo
|
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
51
|
-
|
52
|
-
|
53
|
-
subject.gt_matcher('quantity', 1)
|
51
|
+
%w[gt lt gteq lteq].each do |m|
|
52
|
+
op_name = { 'gteq' => 'gte', 'lteq' => 'lte' }[m] || m
|
54
53
|
|
55
|
-
|
56
|
-
|
57
|
-
|
54
|
+
describe "##{m}_matcher" do
|
55
|
+
it 'returns the matcher' do
|
56
|
+
subject.send "#{m}_matcher", 'quantity', 1
|
58
57
|
|
59
|
-
|
60
|
-
|
61
|
-
subject.lt_matcher('quantity', 1)
|
58
|
+
expect(subject.to_query).to eq('quantity' => { "$#{op_name}" => 1 })
|
59
|
+
end
|
62
60
|
|
63
|
-
|
64
|
-
|
65
|
-
|
61
|
+
it 'accepts time' do
|
62
|
+
updated_at = Time.now
|
63
|
+
subject.send "#{m}_matcher", 'updated_at', updated_at
|
66
64
|
|
67
|
-
|
68
|
-
|
69
|
-
subject.gteq_matcher('quantity', 1)
|
65
|
+
expect(subject.to_query).to eq('updated_at' => { "$#{op_name}" => updated_at })
|
66
|
+
end
|
70
67
|
|
71
|
-
|
72
|
-
|
73
|
-
end
|
68
|
+
it 'accepts time as a string' do
|
69
|
+
updated_at = '2014-10-11 14:48:07 -0300'
|
74
70
|
|
75
|
-
|
76
|
-
|
77
|
-
|
71
|
+
subject.send "#{m}_matcher", 'updated_at', updated_at
|
72
|
+
|
73
|
+
expect(subject.to_query).to eq('updated_at' => { "$#{op_name}" => updated_at })
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'accepts date' do
|
77
|
+
updated_at = Date.new
|
78
78
|
|
79
|
-
|
79
|
+
subject.send "#{m}_matcher", 'updated_at', updated_at
|
80
|
+
|
81
|
+
expect(subject.to_query).to eq('updated_at' => { "$#{op_name}" => updated_at })
|
82
|
+
end
|
80
83
|
end
|
81
84
|
end
|
82
85
|
|
@@ -14,10 +14,6 @@ module RansackMongo
|
|
14
14
|
@query
|
15
15
|
end
|
16
16
|
|
17
|
-
def sanitize(unsanitized)
|
18
|
-
unsanitized
|
19
|
-
end
|
20
|
-
|
21
17
|
def self.predicates
|
22
18
|
PREDICATES
|
23
19
|
end
|
@@ -36,6 +32,19 @@ module RansackMongo
|
|
36
32
|
end
|
37
33
|
|
38
34
|
context 'when MongoAdapter' do
|
35
|
+
describe '#to_query!' do
|
36
|
+
it 'raises exception when query evaluates to an empty hash' do
|
37
|
+
params = { 'name' => 'Pablo' }
|
38
|
+
expect { described_class.new.to_query!(params) }.to raise_error(MatcherNotFound)
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'returns the query' do
|
42
|
+
params = { 'name_eq' => 'Pablo', 'fullname_cont' => 'Cantero' }
|
43
|
+
|
44
|
+
expect(described_class.new.to_query!(params)).to eq('name' => 'Pablo', 'fullname' => /Cantero/i)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
39
48
|
describe '#to_query' do
|
40
49
|
it 'returns the query' do
|
41
50
|
params = { 'name_eq' => 'Pablo', 'fullname_cont' => 'Cantero' }
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ransack_mongo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Pablo Cantero
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-10-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -52,7 +52,7 @@ dependencies:
|
|
52
52
|
- - '>='
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
-
description: Ransack Mongo is
|
55
|
+
description: Ransack Mongo is based on Ransack but for MongoDB
|
56
56
|
email:
|
57
57
|
- pablo@pablocantero.com
|
58
58
|
executables: []
|
@@ -60,6 +60,7 @@ extensions: []
|
|
60
60
|
extra_rdoc_files: []
|
61
61
|
files:
|
62
62
|
- .gitignore
|
63
|
+
- .travis.yml
|
63
64
|
- Gemfile
|
64
65
|
- LICENSE.txt
|
65
66
|
- README.md
|
@@ -74,7 +75,7 @@ files:
|
|
74
75
|
- spec/ransack_mongo/predicate_spec.rb
|
75
76
|
- spec/ransack_mongo/query_spec.rb
|
76
77
|
- spec/spec_helper.rb
|
77
|
-
homepage:
|
78
|
+
homepage: https://github.com/phstc/ransack_mongo
|
78
79
|
licenses:
|
79
80
|
- MIT
|
80
81
|
metadata: {}
|
@@ -97,7 +98,7 @@ rubyforge_project:
|
|
97
98
|
rubygems_version: 2.0.14
|
98
99
|
signing_key:
|
99
100
|
specification_version: 4
|
100
|
-
summary:
|
101
|
+
summary: Query params based searching for MongoDB
|
101
102
|
test_files:
|
102
103
|
- spec/ransack_mongo/mongo_adapter_spec.rb
|
103
104
|
- spec/ransack_mongo/predicate_spec.rb
|