yep_searchable 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.
- data/MIT-LICENSE +20 -0
- data/README.rdoc +163 -0
- data/Rakefile +1 -0
- data/lib/yep_searchable/configuration.rb +25 -0
- data/lib/yep_searchable/searchable_error.rb +5 -0
- data/lib/yep_searchable/searchable_resource.rb +259 -0
- data/lib/yep_searchable/version.rb +3 -0
- data/lib/yep_searchable/yep_resource.rb +104 -0
- data/lib/yep_searchable.rb +32 -0
- data/test/performance/browsing_test.rb +12 -0
- data/test/test_helper.rb +13 -0
- metadata +74 -0
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2012 YOURNAME
|
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,163 @@
|
|
1
|
+
#YepSearchable
|
2
|
+
==============
|
3
|
+
|
4
|
+
This is a ruby gem to search in Ruby models as ActiveRecord::Base and ActiveResources::Base.
|
5
|
+
|
6
|
+
<b>Beta notes:</b> The search is temporarily working as "contains" clauses.
|
7
|
+
|
8
|
+
|
9
|
+
##Installing
|
10
|
+
|
11
|
+
In your Gemfile, add the following line of code:
|
12
|
+
<pre>gem 'yep_searchable'</pre>
|
13
|
+
|
14
|
+
|
15
|
+
##Configuring
|
16
|
+
|
17
|
+
### ActiveRecord Search
|
18
|
+
In your ActiveRecord model, add this line of code:
|
19
|
+
<pre>searchable_resource searchable_columns: [:name, :notes]</pre>
|
20
|
+
|
21
|
+
For example:
|
22
|
+
```ruby
|
23
|
+
class Brand < ActiveRecord::Base
|
24
|
+
|
25
|
+
searchable_resource searchable_columns: [:name]
|
26
|
+
....
|
27
|
+
|
28
|
+
end
|
29
|
+
```
|
30
|
+
|
31
|
+
```ruby
|
32
|
+
class Car < ActiveRecord::Base
|
33
|
+
|
34
|
+
searchable_resource searchable_columns: [:model, :color]
|
35
|
+
|
36
|
+
belongs_to :brand
|
37
|
+
....
|
38
|
+
|
39
|
+
end
|
40
|
+
```
|
41
|
+
|
42
|
+
### ActiveResource Search
|
43
|
+
Your ActiveResource must implement YepSearchable::YepResource, like this:
|
44
|
+
|
45
|
+
```ruby
|
46
|
+
class Brand < YepSearchable::YepResource
|
47
|
+
self.site = "http://127.0.0.1"
|
48
|
+
...
|
49
|
+
end
|
50
|
+
```
|
51
|
+
|
52
|
+
In YepResource you have two new attributes:
|
53
|
+
```ruby
|
54
|
+
...
|
55
|
+
self.search_path = "search_resource" # this is the default value
|
56
|
+
self.search_ids_path = "search_ids" # this is the default value
|
57
|
+
...
|
58
|
+
```
|
59
|
+
|
60
|
+
For each of this path you <b>must create an route and an action on source controller</b>.
|
61
|
+
Example:
|
62
|
+
|
63
|
+
|
64
|
+
```ruby
|
65
|
+
class BrandController < ApplicationController
|
66
|
+
...
|
67
|
+
# GET /brands/search_resource
|
68
|
+
def search_resource
|
69
|
+
@brands = Brand.search(params[:query])
|
70
|
+
|
71
|
+
render json: @brands
|
72
|
+
end
|
73
|
+
|
74
|
+
# GET /brands/search_ids
|
75
|
+
def search_ids
|
76
|
+
ids = Brand.search_only_ids(params[:query])
|
77
|
+
|
78
|
+
render json: ids
|
79
|
+
end
|
80
|
+
...
|
81
|
+
end
|
82
|
+
```
|
83
|
+
|
84
|
+
### Declaring relations between ActiveRecord and YepResource
|
85
|
+
Once you search for "Ferrari" you are expect to receive the cars branded by Ferrari.
|
86
|
+
So in your ActiveRecord "searchable_resource" declaration, you should add the following option:
|
87
|
+
```ruby
|
88
|
+
searchable_resource searchable_columns: [:name, :notes], yep_resources: [{class_name: :brand, foreign_key: :brand_id}]
|
89
|
+
```
|
90
|
+
|
91
|
+
In this case, if you search like this:
|
92
|
+
```ruby
|
93
|
+
Car.search("ferrari")
|
94
|
+
```
|
95
|
+
|
96
|
+
The result will be all cars that contain "Ferrari" in the <b>model</b>, <b>color</b> or the <b>brand_id</b> equal for the brands that contains "ferrari" in the name.
|
97
|
+
Comparing to an SQL command, is something like:
|
98
|
+
```sql
|
99
|
+
SELECT * FROM cars WHERE cars.model LIKE '%FERRARI%' OR cars.color LIKE '%FERRARI%'
|
100
|
+
--here is the trick
|
101
|
+
OR (cars.brand_id IN (SELECT id FROM brands WHERE brands.name LIKE '%FERRARI%'));
|
102
|
+
```
|
103
|
+
|
104
|
+
##Usage
|
105
|
+
The yep_searchable gem provide differents way for search.
|
106
|
+
You can give more than one parameter or not propagate the search.
|
107
|
+
The examples will describe the gem methods.
|
108
|
+
|
109
|
+
### Searching
|
110
|
+
- You can search with more than one parameter:
|
111
|
+
|
112
|
+
```ruby
|
113
|
+
Car.search("ferrari", "red")
|
114
|
+
# this will look for all cars that contain "ferrari" or "red" in the name, color or brand name
|
115
|
+
```
|
116
|
+
|
117
|
+
- You are able to not propagate the search, the search will not look for the relations:
|
118
|
+
|
119
|
+
```ruby
|
120
|
+
Car.search(false, "red")
|
121
|
+
# this will look for all cars that contain "red" in the name or color BUT WILL NOT SEARCH FOR BRANDS THAT CONTAINS "RED" IN THE NAME
|
122
|
+
```
|
123
|
+
|
124
|
+
### Searching only IDS
|
125
|
+
- You can search only the model ids using the method "search_only_ids":
|
126
|
+
|
127
|
+
```ruby
|
128
|
+
Car.search_only_ids("ferrari", "red")
|
129
|
+
# this will look for all cars ids that contain "ferrari" or "red" in the name, color or brand name
|
130
|
+
```
|
131
|
+
|
132
|
+
- As the normal search, you can propagate the search or not:
|
133
|
+
|
134
|
+
```ruby
|
135
|
+
Car.search_only_ids(false, "red")
|
136
|
+
# this will look for all cars ids that contain "red" in the name or color BUT WILL NOT SEARCH FOR BRANDS THAT CONTAINS "RED" IN THE NAME
|
137
|
+
```
|
138
|
+
|
139
|
+
### Pagination
|
140
|
+
- You can paginate your search using the method "search_by_page", the search by page method have the following parameters:
|
141
|
+
- <i><b>only_ids</b> - default false</i>
|
142
|
+
- <i><b>page_number</b> - default nil</i>
|
143
|
+
- <i><b>number_of_rows</b> - default nil - number of rows per page</i>
|
144
|
+
- <i><b>propagate</b> - default true</i>
|
145
|
+
|
146
|
+
Example:
|
147
|
+
|
148
|
+
```ruby
|
149
|
+
Car.search_by_page(false, 1, 30, true, "ferrari", "red")
|
150
|
+
# this will look for the first page, 30 cars
|
151
|
+
# that contain "ferrari" or "red" in the name, color or brand name
|
152
|
+
```
|
153
|
+
|
154
|
+
### Is searchable resource?
|
155
|
+
- The YepSearchable gem provides the capability to check if a Model is searchable by the method "is_searchable_resource?"
|
156
|
+
Example:
|
157
|
+
|
158
|
+
```ruby
|
159
|
+
Car.is_searchable_resource?
|
160
|
+
# => true
|
161
|
+
Motorcycle.is_searchable_resource?
|
162
|
+
# => false
|
163
|
+
```
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
#!/usr/bin/env rake
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module YepSearchable
|
2
|
+
class Configuration
|
3
|
+
attr_accessor :configs
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
@@configs ||= Hash.new
|
7
|
+
end
|
8
|
+
|
9
|
+
def include_option(class_name, option_name, value)
|
10
|
+
@@configs ||= Hash.new
|
11
|
+
@@configs[class_name] ||= Hash.new
|
12
|
+
@@configs[class_name][option_name] = value
|
13
|
+
end
|
14
|
+
|
15
|
+
def retrieve_option(class_name, option_name)
|
16
|
+
@@configs ||= Hash.new
|
17
|
+
|
18
|
+
if @@configs and @@configs[class_name]
|
19
|
+
@@configs[class_name][option_name]
|
20
|
+
else
|
21
|
+
nil
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,259 @@
|
|
1
|
+
require 'yep_searchable/searchable_error'
|
2
|
+
|
3
|
+
module YepSearchable
|
4
|
+
module SearchableResource
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
module ClassMethods
|
8
|
+
def searchable_resource(options = {})
|
9
|
+
if not options[:searchable_columns]
|
10
|
+
raise SearchableError, "Searchable columns must be initialized on searchable_resource declaration"
|
11
|
+
end
|
12
|
+
|
13
|
+
attr_accessor :searchable_columns
|
14
|
+
YepSearchable.configuration.include_option(self.to_s, "searchable_columns", options[:searchable_columns])
|
15
|
+
|
16
|
+
if options[:yep_resources]
|
17
|
+
options[:yep_resources].each do |resource|
|
18
|
+
if resource[:class_name].nil? or resource[:foreign_key].nil?
|
19
|
+
raise SearchableError, "class_name and foreign_key must be declared"
|
20
|
+
end
|
21
|
+
|
22
|
+
if !resource[:class_name].to_s.camelize.constantize.superclass.to_s.eql?"YepSearchable::YepResource"
|
23
|
+
raise SearchableError, "Only classes that implement YepResource are allowed"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
YepSearchable.configuration.include_option(self.to_s, "yep_resources", options[:yep_resources])
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def is_searchable_resource?
|
31
|
+
if YepSearchable.configuration.nil?
|
32
|
+
return false
|
33
|
+
end
|
34
|
+
searchable_columns = YepSearchable.configuration.retrieve_option(self.to_s, 'searchable_columns')
|
35
|
+
if searchable_columns.nil? or searchable_columns.empty?
|
36
|
+
return false
|
37
|
+
else
|
38
|
+
return true
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def search(propagate, *query_params)
|
43
|
+
if !propagate.to_s.eql?"true" and !propagate.to_s.eql?"false"
|
44
|
+
if query_params.nil? or query_params.empty?
|
45
|
+
query_params = []
|
46
|
+
end
|
47
|
+
|
48
|
+
while query_params.first.instance_of?(Array)
|
49
|
+
query_params = query_params.first
|
50
|
+
end
|
51
|
+
query_params << propagate
|
52
|
+
|
53
|
+
propagate = false
|
54
|
+
end
|
55
|
+
|
56
|
+
return search_by_page(false, nil, nil, propagate, query_params)
|
57
|
+
end
|
58
|
+
|
59
|
+
def search_only_ids(propagate, *query_params)
|
60
|
+
if !propagate.to_s.eql?"true" and !propagate.to_s.eql?"false"
|
61
|
+
if query_params.nil? or query_params.empty?
|
62
|
+
query_params = []
|
63
|
+
end
|
64
|
+
|
65
|
+
while query_params.first.instance_of?(Array)
|
66
|
+
query_params = query_params.first
|
67
|
+
end
|
68
|
+
query_params << propagate
|
69
|
+
|
70
|
+
propagate = false
|
71
|
+
end
|
72
|
+
|
73
|
+
return search_by_page(true, nil, nil, propagate, query_params)
|
74
|
+
end
|
75
|
+
|
76
|
+
def search_by_page(only_ids = false, page = nil, number_of_rows = nil, propagate = true, *query_param)
|
77
|
+
while query_param.first.instance_of?(Array)
|
78
|
+
query_param = query_param.first
|
79
|
+
end
|
80
|
+
|
81
|
+
if query_param.size == 1 and query_param.first.include?("$$$")
|
82
|
+
query_param = query_param.first.split("$$$")
|
83
|
+
end
|
84
|
+
|
85
|
+
if query_param.nil? or query_param.empty?
|
86
|
+
raise SearchableError, "Arguments not declared in search method"
|
87
|
+
end
|
88
|
+
|
89
|
+
if page
|
90
|
+
is_valid = Integer(page.to_s) rescue false
|
91
|
+
if !is_valid and is_valid <= 0
|
92
|
+
raise SearchableError, "Argument page must be a valid number"
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
if number_of_rows
|
97
|
+
is_valid = Integer(number_of_rows.to_s) rescue false
|
98
|
+
if !is_valid and is_valid <= 0
|
99
|
+
raise SearchableError, "Argument number_of_rows must be a valid number"
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
# query_param = arguments.split("$$$")
|
104
|
+
query_string = nil
|
105
|
+
|
106
|
+
searchable_columns = YepSearchable.configuration.retrieve_option(self.to_s, 'searchable_columns')
|
107
|
+
if not searchable_columns
|
108
|
+
raise SearchableError, "Model must have searchable_resource declaration"
|
109
|
+
end
|
110
|
+
|
111
|
+
query_param.each do |arg|
|
112
|
+
if query_string.nil?
|
113
|
+
query_string = "("
|
114
|
+
else
|
115
|
+
query_string = "#{query_string} OR ("
|
116
|
+
end
|
117
|
+
|
118
|
+
searchable_columns.each do |column|
|
119
|
+
if query_string.last == "("
|
120
|
+
query_string = "#{query_string} #{column.to_s} LIKE '%#{arg}%'"
|
121
|
+
else
|
122
|
+
query_string = "#{query_string} OR #{column.to_s} LIKE '%#{arg}%'"
|
123
|
+
end
|
124
|
+
end
|
125
|
+
query_string = "#{query_string})"
|
126
|
+
end
|
127
|
+
|
128
|
+
if propagate
|
129
|
+
relation_query_string = get_where_relations(query_param)
|
130
|
+
|
131
|
+
if !relation_query_string.nil? and !relation_query_string.empty?
|
132
|
+
if !query_string.nil? and !query_string.empty?
|
133
|
+
query_string = "#{query_string} OR #{relation_query_string})"
|
134
|
+
else
|
135
|
+
query_string = "#{relation_query_string}"
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
relation_query_string = get_where_yep_resources(query_param)
|
140
|
+
|
141
|
+
if !relation_query_string.nil? and !relation_query_string.empty?
|
142
|
+
if !query_string.nil? and !query_string.empty?
|
143
|
+
query_string = "#{query_string} OR #{relation_query_string})"
|
144
|
+
else
|
145
|
+
query_string = "#{relation_query_string}"
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
if only_ids
|
151
|
+
entity = []
|
152
|
+
|
153
|
+
if page.nil? or number_of_rows.nil?
|
154
|
+
entity = self.select(:id).where(query_string)
|
155
|
+
else
|
156
|
+
entity = self.select(:id).paginate(page: page, per_page: number_of_rows).where(query_string)
|
157
|
+
end
|
158
|
+
|
159
|
+
return_value = []
|
160
|
+
|
161
|
+
entity.each do |ent|
|
162
|
+
return_value << ent.id
|
163
|
+
end
|
164
|
+
|
165
|
+
return return_value
|
166
|
+
else
|
167
|
+
return_value = []
|
168
|
+
if page.nil? or number_of_rows.nil?
|
169
|
+
return_value = self.where(query_string)
|
170
|
+
else
|
171
|
+
return_value = self.paginate(page: page, per_page: number_of_rows).where(query_string)
|
172
|
+
end
|
173
|
+
return return_value
|
174
|
+
end
|
175
|
+
|
176
|
+
end
|
177
|
+
|
178
|
+
private
|
179
|
+
def get_where_relations(query_array)
|
180
|
+
while query_array.first.instance_of?(Array)
|
181
|
+
query_array = query_array.first
|
182
|
+
end
|
183
|
+
|
184
|
+
query_string = ""
|
185
|
+
|
186
|
+
reflec_keys = self.reflections.keys
|
187
|
+
|
188
|
+
reflec_keys.each do |reflection_key|
|
189
|
+
reflection = self.reflections[reflection_key]
|
190
|
+
|
191
|
+
if reflection.macro.to_s.eql?("belongs_to") and reflection.class_name.constantize.is_searchable_resource?
|
192
|
+
ids = reflection.class_name.constantize.search_only_ids(query_array)
|
193
|
+
|
194
|
+
if ids.nil? or ids.empty?
|
195
|
+
next
|
196
|
+
end
|
197
|
+
|
198
|
+
if query_string.empty?
|
199
|
+
query_string = "(#{reflection.foreign_key} IN ("
|
200
|
+
else
|
201
|
+
query_string = "#{query_string} OR (#{reflection.foreign_key} IN ("
|
202
|
+
end
|
203
|
+
|
204
|
+
ids.each do |entity_id|
|
205
|
+
query_string = "#{query_string} #{entity_id},"
|
206
|
+
end
|
207
|
+
|
208
|
+
query_string = query_string[0, query_string.size - 1]
|
209
|
+
query_string = "#{query_string})"
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
return query_string
|
214
|
+
|
215
|
+
end
|
216
|
+
|
217
|
+
def get_where_yep_resources(query_array)
|
218
|
+
while query_array.first.instance_of?(Array)
|
219
|
+
query_array = query_array.first
|
220
|
+
end
|
221
|
+
yep_res = YepSearchable.configuration.retrieve_option(self.to_s, 'yep_resources')
|
222
|
+
|
223
|
+
if yep_res.nil? or yep_res.empty?
|
224
|
+
return nil
|
225
|
+
end
|
226
|
+
|
227
|
+
query_string = ""
|
228
|
+
|
229
|
+
yep_res.each do |resource|
|
230
|
+
if !resource[:class_name].to_s.camelize.constantize.superclass.to_s.eql?"YepSearchable::YepResource"
|
231
|
+
raise SearchableError, "Only classes that implement YepResource are allowed"
|
232
|
+
end
|
233
|
+
|
234
|
+
ids = resource[:class_name].to_s.camelize.constantize.search_only_ids(query_array)
|
235
|
+
|
236
|
+
if ids.nil? or ids.empty?
|
237
|
+
next
|
238
|
+
end
|
239
|
+
|
240
|
+
if query_string.empty?
|
241
|
+
query_string = "(#{resource[:foreign_key]} IN ("
|
242
|
+
else
|
243
|
+
query_string = "#{query_string} OR (#{resource[:foreign_key]} IN ("
|
244
|
+
end
|
245
|
+
|
246
|
+
ids.each do |entity_id|
|
247
|
+
query_string = "#{query_string} #{entity_id},"
|
248
|
+
end
|
249
|
+
|
250
|
+
query_string = query_string[0, query_string.size - 1]
|
251
|
+
query_string = "#{query_string})"
|
252
|
+
|
253
|
+
end
|
254
|
+
|
255
|
+
return query_string
|
256
|
+
end
|
257
|
+
end
|
258
|
+
end
|
259
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'uri'
|
3
|
+
require 'active_resource'
|
4
|
+
|
5
|
+
module YepSearchable
|
6
|
+
class YepResource < ActiveResource::Base
|
7
|
+
|
8
|
+
class << self
|
9
|
+
attr_accessor :search_path, :search_ids_path
|
10
|
+
end
|
11
|
+
|
12
|
+
self.search_path = nil
|
13
|
+
self.search_ids_path = nil
|
14
|
+
|
15
|
+
def self.search_only_ids(*arguments)
|
16
|
+
if arguments.nil? or arguments.size == 0
|
17
|
+
return nil
|
18
|
+
end
|
19
|
+
|
20
|
+
while arguments.first.instance_of?(Array)
|
21
|
+
arguments = arguments.first
|
22
|
+
end
|
23
|
+
|
24
|
+
query_params = nil
|
25
|
+
|
26
|
+
arguments.each do |arg|
|
27
|
+
if query_params.nil?
|
28
|
+
query_params = "#{arg}"
|
29
|
+
else
|
30
|
+
query_params = "#{query_params}$$$#{arg}"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
begin
|
35
|
+
search_route = "search_ids"
|
36
|
+
if not self.search_ids_path.nil?
|
37
|
+
search_route = self.search_ids_path
|
38
|
+
end
|
39
|
+
|
40
|
+
search_uri = "#{self.site}#{self.element_path(search_route)}?query=#{query_params}"
|
41
|
+
search_uri = search_uri.gsub("//", "/")
|
42
|
+
search_uri = search_uri.gsub("http:/", "http://")
|
43
|
+
search_uri = search_uri.gsub("https:/", "https://")
|
44
|
+
|
45
|
+
search_result = Net::HTTP.get(URI.parse(search_uri))
|
46
|
+
|
47
|
+
result = JSON.parse(search_result)
|
48
|
+
return result
|
49
|
+
rescue => error
|
50
|
+
puts "\nError - #{error.message}\n"
|
51
|
+
return nil
|
52
|
+
ensure
|
53
|
+
# finally
|
54
|
+
end
|
55
|
+
|
56
|
+
return nil
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
def self.search(*arguments)
|
61
|
+
if arguments.nil? or arguments.size == 0
|
62
|
+
return nil
|
63
|
+
end
|
64
|
+
|
65
|
+
while arguments.first.instance_of?(Array)
|
66
|
+
arguments = arguments.first
|
67
|
+
end
|
68
|
+
|
69
|
+
query_params = nil
|
70
|
+
|
71
|
+
arguments.each do |arg|
|
72
|
+
if query_params.nil?
|
73
|
+
query_params = "#{arg}"
|
74
|
+
else
|
75
|
+
query_params = "#{query_params}$$$#{arg}"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
begin
|
80
|
+
search_route = "search_resource"
|
81
|
+
if not self.search_path.nil?
|
82
|
+
search_route = self.search_path
|
83
|
+
end
|
84
|
+
|
85
|
+
search_uri = "#{self.site}#{self.element_path(search_route)}?query=#{query_params}"
|
86
|
+
search_uri = search_uri.gsub("//", "/")
|
87
|
+
search_uri = search_uri.gsub("http:/", "http://")
|
88
|
+
search_uri = search_uri.gsub("https:/", "https://")
|
89
|
+
|
90
|
+
search_result = Net::HTTP.get(URI.parse(search_uri))
|
91
|
+
|
92
|
+
result = JSON.parse(search_result)
|
93
|
+
return result
|
94
|
+
rescue => error
|
95
|
+
puts "\nError - #{error.message}\n"
|
96
|
+
return nil
|
97
|
+
ensure
|
98
|
+
# finally
|
99
|
+
end
|
100
|
+
|
101
|
+
return nil
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'yep_searchable/configuration'
|
2
|
+
require 'yep_searchable/yep_resource'
|
3
|
+
require 'yep_searchable/searchable_resource'
|
4
|
+
|
5
|
+
module YepSearchable
|
6
|
+
@@configuration = Configuration.new
|
7
|
+
|
8
|
+
def self.configuration
|
9
|
+
@@configuration ||= Configuration.new
|
10
|
+
@@configuration
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.configure
|
14
|
+
self.configuration ||= Configuration.new
|
15
|
+
yield(configuration)
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.included(mod)
|
19
|
+
mod.extend(ClassMethods)
|
20
|
+
end
|
21
|
+
|
22
|
+
class << self
|
23
|
+
attr_accessor :searchable_class
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# reopen ActiveRecord and include all the above to make
|
28
|
+
# them available to all our models if they want it
|
29
|
+
|
30
|
+
ActiveRecord::Base.class_eval do
|
31
|
+
include YepSearchable::SearchableResource
|
32
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'rails/performance_test_help'
|
3
|
+
|
4
|
+
class BrowsingTest < ActionDispatch::PerformanceTest
|
5
|
+
# Refer to the documentation for all available options
|
6
|
+
# self.profile_options = { :runs => 5, :metrics => [:wall_time, :memory]
|
7
|
+
# :output => 'tmp/performance', :formats => [:flat] }
|
8
|
+
|
9
|
+
def test_homepage
|
10
|
+
get '/'
|
11
|
+
end
|
12
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
ENV["RAILS_ENV"] = "test"
|
2
|
+
require File.expand_path('../../config/environment', __FILE__)
|
3
|
+
require 'rails/test_help'
|
4
|
+
|
5
|
+
class ActiveSupport::TestCase
|
6
|
+
# Setup all fixtures in test/fixtures/*.(yml|csv) for all tests in alphabetical order.
|
7
|
+
#
|
8
|
+
# Note: You'll currently still have to declare fixtures explicitly in integration tests
|
9
|
+
# -- they do not yet inherit this setting
|
10
|
+
fixtures :all
|
11
|
+
|
12
|
+
# Add more helper methods to be used by all tests here...
|
13
|
+
end
|
metadata
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: yep_searchable
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Luiz Santana
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-01-18 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rails
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 3.2.0
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 3.2.0
|
30
|
+
description: Lib for search using ActiveRecord and ActiveResource
|
31
|
+
email:
|
32
|
+
- luiz.santana@yepdev.com
|
33
|
+
executables: []
|
34
|
+
extensions: []
|
35
|
+
extra_rdoc_files: []
|
36
|
+
files:
|
37
|
+
- lib/yep_searchable/configuration.rb
|
38
|
+
- lib/yep_searchable/searchable_error.rb
|
39
|
+
- lib/yep_searchable/searchable_resource.rb
|
40
|
+
- lib/yep_searchable/version.rb
|
41
|
+
- lib/yep_searchable/yep_resource.rb
|
42
|
+
- lib/yep_searchable.rb
|
43
|
+
- MIT-LICENSE
|
44
|
+
- Rakefile
|
45
|
+
- README.rdoc
|
46
|
+
- test/performance/browsing_test.rb
|
47
|
+
- test/test_helper.rb
|
48
|
+
homepage: http://yepdev.com
|
49
|
+
licenses: []
|
50
|
+
post_install_message:
|
51
|
+
rdoc_options: []
|
52
|
+
require_paths:
|
53
|
+
- lib
|
54
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
55
|
+
none: false
|
56
|
+
requirements:
|
57
|
+
- - ! '>='
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: '0'
|
60
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
requirements: []
|
67
|
+
rubyforge_project:
|
68
|
+
rubygems_version: 1.8.24
|
69
|
+
signing_key:
|
70
|
+
specification_version: 3
|
71
|
+
summary: YepSearchable-0.0.2
|
72
|
+
test_files:
|
73
|
+
- test/performance/browsing_test.rb
|
74
|
+
- test/test_helper.rb
|