mongoid_query_string_interface 0.1.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.
- data/MIT_LICENSE +20 -0
- data/README.rdoc +83 -0
- data/lib/mongoid_query_string_interface.rb +175 -0
- data/lib/version.rb +6 -0
- metadata +106 -0
data/MIT_LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2010 Vicente Mundim
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
= Overview
|
2
|
+
|
3
|
+
== About Mongoid::QueryStringInterace
|
4
|
+
|
5
|
+
Gives a method that can parse query string parameters into a set of criterias
|
6
|
+
that Mongoid can use to perform actual queries in MongoDB databases for a given
|
7
|
+
model.
|
8
|
+
|
9
|
+
== Repository
|
10
|
+
|
11
|
+
http://github.com/vicentemundim/mongoid-query-string-interface
|
12
|
+
|
13
|
+
= Installing
|
14
|
+
|
15
|
+
This is a gem, so you can install it by:
|
16
|
+
|
17
|
+
sudo gem install mongoid_query_string_interface
|
18
|
+
|
19
|
+
Or, if you are using rails, put this in your Gemfile:
|
20
|
+
|
21
|
+
gem 'mongoid_query_string_interface'
|
22
|
+
|
23
|
+
= Usage
|
24
|
+
|
25
|
+
To use it, just extend Mongoid::QueryStringInterface in your document model:
|
26
|
+
|
27
|
+
class Document
|
28
|
+
include Mongoid::Document
|
29
|
+
extend Mongoid::QueryInterfaceString
|
30
|
+
|
31
|
+
# ... add fields here
|
32
|
+
end
|
33
|
+
|
34
|
+
Then, in your controllers put:
|
35
|
+
|
36
|
+
def index
|
37
|
+
@documents = Document.filter_by(params)
|
38
|
+
# ... do something like render a HTML template or a XML/JSON view of documents
|
39
|
+
end
|
40
|
+
|
41
|
+
That's it! Now you can do something like this:
|
42
|
+
|
43
|
+
http://myhost.com/documents?tags.all=ruby|rails|mongodb&tags.nin=sql|java&updated_at.gt=2010-01-01&created_at.desc&per_page=10&page=3
|
44
|
+
|
45
|
+
This would get all documents which have the tags 'ruby', 'rails' and 'mongo',
|
46
|
+
and that don't have both 'sql' and 'java' tags, and that were updated after
|
47
|
+
2010-01-01, ordered by descending created_at. It will return 10 elements per
|
48
|
+
page, and the 3rd page of results.
|
49
|
+
|
50
|
+
You could even query for embedded documents, and use any of the Mongodb
|
51
|
+
conditional operators:
|
52
|
+
|
53
|
+
http://myhost.com/documents?comments.author=Shrek
|
54
|
+
|
55
|
+
Which would get all documents that have been commented by 'Shrek'. Basically,
|
56
|
+
any valid path that you can use in a Mongoid::Criteria can be used here, and
|
57
|
+
you can also append any of the Mongodb conditional operators.
|
58
|
+
|
59
|
+
You can sort results like this:
|
60
|
+
|
61
|
+
http://myhost.com/documents?order_by=created_at.desc
|
62
|
+
|
63
|
+
or
|
64
|
+
|
65
|
+
http://myhost.com/documents?order_by=created_at
|
66
|
+
|
67
|
+
Which is the same as:
|
68
|
+
|
69
|
+
http://myhost.com/documents?order_by=created_at.asc
|
70
|
+
|
71
|
+
To order by more than one field:
|
72
|
+
|
73
|
+
http://myhost.com/documents?created_at.desc&updated_at.desc
|
74
|
+
|
75
|
+
Or even:
|
76
|
+
|
77
|
+
http://myhost.com/documents?created_at=desc&updated_at=desc
|
78
|
+
|
79
|
+
Check the specs for more use cases.
|
80
|
+
|
81
|
+
= Credits
|
82
|
+
|
83
|
+
Vicente Mundim: vicente.mundim at gmail dot com
|
@@ -0,0 +1,175 @@
|
|
1
|
+
module Mongoid
|
2
|
+
module QueryStringInterface
|
3
|
+
CONDITIONAL_OPERATORS = [:all, :exists, :gte, :gt, :in, :lte, :lt, :ne, :nin, :size, :near, :within]
|
4
|
+
ARRAY_CONDITIONAL_OPERATORS = [:all, :in, :nin]
|
5
|
+
SORTING_OPERATORS = [:asc, :desc]
|
6
|
+
|
7
|
+
def filter_by(params={})
|
8
|
+
params = hash_with_indifferent_access(params)
|
9
|
+
where(filtering_options(params)).order_by(*sorting_options(params)).paginate(pagination_options(params))
|
10
|
+
end
|
11
|
+
|
12
|
+
def paginated_collection_with_filter_by(params={})
|
13
|
+
params = hash_with_indifferent_access(params)
|
14
|
+
|
15
|
+
pagination = pagination_options(params)
|
16
|
+
pager = WillPaginate::Collection.new pagination[:page], pagination[:per_page], where(filtering_options(params)).count
|
17
|
+
|
18
|
+
[:total_entries, :total_pages, :per_page, :offset, :previous_page, :current_page, :next_page].inject({}) do |result, attr|
|
19
|
+
result[attr] = pager.send(attr)
|
20
|
+
result
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def default_filtering_options
|
25
|
+
{}
|
26
|
+
end
|
27
|
+
|
28
|
+
def default_sorting_options
|
29
|
+
[]
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
def pagination_options(options)
|
34
|
+
options.reverse_merge :per_page => 12, :page => 1
|
35
|
+
end
|
36
|
+
|
37
|
+
def filtering_options(options)
|
38
|
+
default_filtering_options.merge(parse_operators(only_filtering(options)))
|
39
|
+
end
|
40
|
+
|
41
|
+
def sorting_options(options)
|
42
|
+
options = only_sorting(options)
|
43
|
+
|
44
|
+
sorting_options = []
|
45
|
+
sorting_options.concat(parse_order_by(options))
|
46
|
+
sorting_options.concat(parse_sorting(options))
|
47
|
+
|
48
|
+
sorting_options.empty? ? default_sorting_options : sorting_options
|
49
|
+
end
|
50
|
+
|
51
|
+
def parse_operators(options)
|
52
|
+
options.inject({}) do |result, item|
|
53
|
+
key, value = item
|
54
|
+
|
55
|
+
attribute = attribute_from(key)
|
56
|
+
operator = operator_from(key)
|
57
|
+
value = parse_value(value, operator)
|
58
|
+
|
59
|
+
if operator
|
60
|
+
filter = { operator => value }
|
61
|
+
|
62
|
+
if result.has_key?(attribute)
|
63
|
+
result[attribute].merge!(filter)
|
64
|
+
else
|
65
|
+
result[attribute] = filter
|
66
|
+
end
|
67
|
+
else
|
68
|
+
result[attribute] = value
|
69
|
+
end
|
70
|
+
|
71
|
+
result
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def attribute_from(key)
|
76
|
+
if match = key.match(/(.*)\.(#{(CONDITIONAL_OPERATORS + SORTING_OPERATORS).join('|')})/)
|
77
|
+
match[1].to_sym
|
78
|
+
else
|
79
|
+
key.to_sym
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def operator_from(key)
|
84
|
+
if match = key.match(/.*\.(#{CONDITIONAL_OPERATORS.join('|')})/)
|
85
|
+
"$#{match[1]}".to_sym
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def parse_value(value, operator)
|
90
|
+
parse_date(value) or parse_integer(value) or parse_array(value, operator) or value
|
91
|
+
end
|
92
|
+
|
93
|
+
def parse_date(date)
|
94
|
+
date.to_time and Time.parse(date)
|
95
|
+
rescue Exception
|
96
|
+
nil
|
97
|
+
end
|
98
|
+
|
99
|
+
def parse_integer(integer)
|
100
|
+
if match = integer.match(/\d+/)
|
101
|
+
match[0].to_i
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def parse_float(float)
|
106
|
+
if match = float.match(/^(\d+)(\.?\d*)$/)
|
107
|
+
match[0].to_f
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def parse_array(value, operator)
|
112
|
+
split_and_strip(value) if array_operator?(operator)
|
113
|
+
end
|
114
|
+
|
115
|
+
def array_operator?(operator)
|
116
|
+
ARRAY_CONDITIONAL_OPERATORS.map { |op| "$#{op}" }.include?(operator.to_s)
|
117
|
+
end
|
118
|
+
|
119
|
+
def split_and_strip(values)
|
120
|
+
values.split('|').map(&:strip)
|
121
|
+
end
|
122
|
+
|
123
|
+
def hash_with_indifferent_access(params)
|
124
|
+
params.is_a?(HashWithIndifferentAccess) ? params : HashWithIndifferentAccess.new(params)
|
125
|
+
end
|
126
|
+
|
127
|
+
def only_filtering(options)
|
128
|
+
options.except(*only_sorting(options).keys).except(:per_page, :page, :action, :controller, :format, :order_by)
|
129
|
+
end
|
130
|
+
|
131
|
+
def only_sorting(options)
|
132
|
+
options.inject({}) do |result, item|
|
133
|
+
key, value = item
|
134
|
+
result[key] = value if sorting_parameter?(key, value)
|
135
|
+
result
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
def sorting_parameter?(key, value)
|
140
|
+
key.to_s == 'order_by' or key.match(/(.*)\.(#{SORTING_OPERATORS.join('|')})/) or SORTING_OPERATORS.include?(value.to_sym)
|
141
|
+
end
|
142
|
+
|
143
|
+
def parse_order_by(options)
|
144
|
+
sorting_options = []
|
145
|
+
|
146
|
+
if order_by = options.delete('order_by')
|
147
|
+
if match = order_by.match(/(.*)\.(#{SORTING_OPERATORS.join('|')})/)
|
148
|
+
sorting_options << match[1].to_sym.send(match[2])
|
149
|
+
else
|
150
|
+
sorting_options << order_by.to_sym.asc
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
sorting_options
|
155
|
+
end
|
156
|
+
|
157
|
+
def parse_sorting(options)
|
158
|
+
options.inject([]) do |result, item|
|
159
|
+
key, value = item
|
160
|
+
|
161
|
+
attribute = attribute_from(key)
|
162
|
+
sorting_operator = sorting_operator_from(key)
|
163
|
+
|
164
|
+
result << attribute.send(sorting_operator || value)
|
165
|
+
result
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
def sorting_operator_from(key)
|
170
|
+
if match = key.match(/.*\.(#{SORTING_OPERATORS.join('|')})/)
|
171
|
+
match[1].to_sym
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
data/lib/version.rb
ADDED
metadata
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mongoid_query_string_interface
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 27
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 0
|
10
|
+
version: 0.1.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Vicente Mundim
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-07-22 00:00:00 -03:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: mongoid
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 31098209
|
30
|
+
segments:
|
31
|
+
- 2
|
32
|
+
- 0
|
33
|
+
- 0
|
34
|
+
- beta
|
35
|
+
version: 2.0.0.beta
|
36
|
+
type: :runtime
|
37
|
+
version_requirements: *id001
|
38
|
+
- !ruby/object:Gem::Dependency
|
39
|
+
name: rspec
|
40
|
+
prerelease: false
|
41
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ~>
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
hash: 31098209
|
47
|
+
segments:
|
48
|
+
- 2
|
49
|
+
- 0
|
50
|
+
- 0
|
51
|
+
- beta
|
52
|
+
version: 2.0.0.beta
|
53
|
+
type: :development
|
54
|
+
version_requirements: *id002
|
55
|
+
description: Gives a method that can parse query string parameters into a set of criterias that Mongoid can use to perform actual queries in MongoDB databases for a given model.
|
56
|
+
email:
|
57
|
+
- vicente.mundim@gmail.com
|
58
|
+
executables: []
|
59
|
+
|
60
|
+
extensions: []
|
61
|
+
|
62
|
+
extra_rdoc_files: []
|
63
|
+
|
64
|
+
files:
|
65
|
+
- lib/mongoid_query_string_interface.rb
|
66
|
+
- lib/version.rb
|
67
|
+
- MIT_LICENSE
|
68
|
+
- README.rdoc
|
69
|
+
has_rdoc: true
|
70
|
+
homepage: http://github.com/vicentemundim/mongoid_query_string_interface
|
71
|
+
licenses: []
|
72
|
+
|
73
|
+
post_install_message:
|
74
|
+
rdoc_options: []
|
75
|
+
|
76
|
+
require_paths:
|
77
|
+
- lib
|
78
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
79
|
+
none: false
|
80
|
+
requirements:
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
hash: 3
|
84
|
+
segments:
|
85
|
+
- 0
|
86
|
+
version: "0"
|
87
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
88
|
+
none: false
|
89
|
+
requirements:
|
90
|
+
- - ">="
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
hash: 23
|
93
|
+
segments:
|
94
|
+
- 1
|
95
|
+
- 3
|
96
|
+
- 6
|
97
|
+
version: 1.3.6
|
98
|
+
requirements: []
|
99
|
+
|
100
|
+
rubyforge_project: mongoid_query_string_interface
|
101
|
+
rubygems_version: 1.3.7
|
102
|
+
signing_key:
|
103
|
+
specification_version: 3
|
104
|
+
summary: An interface for performing queries in MongoDB using query string parameters.
|
105
|
+
test_files: []
|
106
|
+
|