glasses 1.6.2 → 1.7.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.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/lib/glasses.rb +254 -10
  3. data/lib/glasses/version.rb +1 -1
  4. data/spec/dummy/app/controllers/search_controller.rb +29 -17
  5. data/spec/dummy/app/views/search/full_raw_search_range.html.erb +0 -0
  6. data/spec/dummy/app/views/search/full_search.html.erb +0 -0
  7. data/spec/dummy/app/views/search/full_search_range.html.erb +0 -0
  8. data/spec/dummy/app/views/search/range_search.html.erb +30 -0
  9. data/spec/dummy/app/views/search/raw_full_search.html.erb +0 -0
  10. data/spec/dummy/app/views/search/raw_range_search.html.erb +25 -0
  11. data/spec/dummy/app/views/search/simple_search.html.erb +4 -2
  12. data/spec/dummy/config/routes.rb +3 -54
  13. data/spec/dummy/db/development.sqlite3 +0 -0
  14. data/spec/dummy/db/seeds.rb +2 -1
  15. data/spec/dummy/db/test.sqlite3 +0 -0
  16. data/spec/dummy/log/development.log +2628 -0
  17. data/spec/dummy/log/test.log +42280 -0
  18. data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/-n4kyDOdRxiiiIJEFA9cId9azJmW5g6hmwbs8SJ4qRg.cache +1 -0
  19. data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/2SBt5E86bhaTcl7TkcrIXPVQyQtH9yIRArRC_UxPck4.cache +1 -0
  20. data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/2Tqd0MZWTPMTu8CoqlOCudnpF2UapAVb-1Qd3gZnzWs.cache +0 -0
  21. data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/4m7rzZ6NLrCLYY8Klx2qByvjsF9EwTrhkqhffC_ddIU.cache +1 -0
  22. data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/4wucpOHsDYdErjU4sC9i1FT33L-WRugEHtfQdiz-CXY.cache +0 -0
  23. data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/AE40Tp96RkdOo7EhY00dhAOG17GUBn6QkZxp0HQVRQA.cache +2 -0
  24. data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/CtIOdYL64ZUZ8_1ALDOZWNEis9WeBXUYTZ95MGCwJxk.cache +2 -0
  25. data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/DMb_4zR5zBmQGRtZlXIrUCrkOrY-Wzw_ESjc3NoXX6s.cache +1 -0
  26. data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/FfRbjoX7fHHQqnXiehqlD233T1kj4rzNPybfmQ_GUWI.cache +2 -0
  27. data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/JlLKJj3SMeXmPLYJvdO955A6OPH9wSTWF3QFOvbaT0k.cache +2 -0
  28. data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/Mo_r4nJu9qt0iEhVH0CXGZkIh_SCKfu3LoDU6GlMT-U.cache +2 -0
  29. data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/PjzZwmbYJUPXBPEKfYAIld32mtAk3H0hBz7ONWVqza4.cache +2 -0
  30. data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/QYBC6SiWic96YuGP27vORM8frM2yoCxYATSeAuu3q3s.cache +2 -0
  31. data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/QfZ4TPv_vTZ6WmGKJEhbsZ0Ou73XHsnuUlsaYV3ZQEY.cache +1 -0
  32. data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/XIp7H1NvI9qObEEUnVrJoJ0TgF9dsNRmdw7bkMLyf64.cache +1 -0
  33. data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/aCkopDHgOZcXcLJcYI3sgc_SuAZhhr9RkRQshzmldF8.cache +1 -0
  34. data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/bkZWDwb871tTLoM-W80twc_qhQ_ziPfInIfbzCcLnpE.cache +1 -0
  35. data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/gLJlx0p_IOKb7r9m3hjLdN2jGSicQ_Ns4SS1jWlFDAQ.cache +0 -0
  36. data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/i9TsnRfu6oqRsV9V2v_6Ulubst2IVveepQEkimUU6QE.cache +1 -0
  37. data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/iEVE5Kzzv15cyQWfQGEbgnKSSO0xiblZzP-sO26AYGQ.cache +0 -0
  38. data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/rRXYm5yDdh2lrn8etfERia5zGqWg3_cJ3siQQG6h9UU.cache +0 -0
  39. data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/t3hd5M5Qs7xWqz8gFCvXf781-4lYaem1SZCLRh47qCc.cache +1 -0
  40. data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/yHIJ2OseWB_qclWx7fwHLHPAVYOch64QqS8Y07WHhRk.cache +0 -0
  41. data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/yuW5Zfj9wAku7kLsnPBHwLsetLDeWKm9ju_dm_GLgf0.cache +1 -0
  42. data/spec/features/full_search_form_test.rb +0 -0
  43. data/spec/features/range_search_form_test.rb +79 -0
  44. data/spec/features/search_performance_test_in_app.rb +0 -0
  45. data/spec/features/simple_search_form_test.rb +34 -9
  46. data/spec/glasses_spec.rb +8 -1
  47. data/spec/test_only_methods/example_only_methods.rb +65 -0
  48. data/spec/tests/full_search_test.rb +63 -0
  49. data/spec/tests/parameters_priority_test.rb +51 -0
  50. data/spec/tests/performance_test.rb +0 -0
  51. data/spec/tests/range_search_test.rb +43 -0
  52. data/spec/tests/sanitized_search_test.rb +19 -7
  53. data/spec/tests/search_test.rb +18 -8
  54. metadata +78 -4
  55. data/spec/scratches/example_only_methods.rb +0 -26
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 81b4a3f6ecf453f6dea81f38a47b4a8ff565b4f9
4
- data.tar.gz: dfdab14e69ad85470a713471e87d98fc3b101227
3
+ metadata.gz: 13db292133e47a1ff62d1b2883a0ded68a386683
4
+ data.tar.gz: a9f1733f0750ae3271ee4b25d338f319f0631fdf
5
5
  SHA512:
6
- metadata.gz: 3046f685eb761093d9036f63164056055c67e73321e5ca8bbf641aa4967e4a2b98762b77ec40b5e0381f7077ec5131b60aa81e70b011b8e96465deaac19f619f
7
- data.tar.gz: 7574e7d304d52100dd82f64ed60c06e5a1f30aef29c47f450880dd80a45e059c5741719f352fe2c9e48c6c85edd7011f9e0b8a45b55b1fdb5c0831bcca506631
6
+ metadata.gz: 01dfee05abdcdba4886d9e7e040355a6c39237f2312026bcf2e4ed7ebb6ab6c90a88c272f7e482733fb8637abcf1e80dba8fd761388213e11db361e24ca41e81
7
+ data.tar.gz: 29577cb0555a7efa09c548cd613713cedecf4a1d6e4eb19377b649d2eb6a5bda33744c7b63cdb25ccb1445ef62b1d6dbd55c0cce8fef1805b363a8e0e1d75dc7
@@ -2,11 +2,212 @@ require "glasses/version"
2
2
 
3
3
  module Glasses
4
4
 
5
+ def self.prioritize_ints_over_strings(columns_to_search, values_to_search)
6
+ # Order params, prioritize ids and bools over over strings to boost performance at database hits.
7
+ for i in (0..columns_to_search.size-1) do
8
+ if columns_to_search[i][columns_to_search[i].size-3] == "E" #if it's a "like" statement
9
+ columns_to_search.insert(0, columns_to_search.delete_at(i))
10
+ values_to_search.insert(0, values_to_search.delete_at(i))
11
+ end
12
+ end
13
+ return [columns_to_search, values_to_search]
14
+ end
15
+
16
+ def self.prioritize_ints_over_strings_and_ranges(columns_to_search, values_to_search)
17
+ # Order params, prioritize ids and bools over ranges and both of these over strings to boost performance at database hits.
18
+ string_shifts = 0
19
+ total_columns = columns_to_search.size - 1
20
+ for i in (0..total_columns) do
21
+ if columns_to_search[i][columns_to_search[i].size-3] == "E" #if it's a "like" statement
22
+ columns_to_search.insert(0, columns_to_search.delete_at(i))
23
+ values_to_search.insert(0, values_to_search.delete_at(i))
24
+ string_shifts += 1
25
+ end
26
+ end
27
+ if string_shifts < total_columns # string_shifts will begin at the 'last index which contains a string' + 1
28
+ for i in (string_shifts..columns_to_search.size-1) do
29
+ if columns_to_search[i][columns_to_search[i].size-4] != " " #if it's empty at this index, value is a range;
30
+ columns_to_search.insert(string_shifts, columns_to_search.delete_at(i))
31
+ values_to_search.insert(string_shifts, values_to_search.delete_at(i))
32
+ end
33
+ end
34
+ end
35
+ return [columns_to_search, values_to_search]
36
+ end
37
+
5
38
  def self.search(model_to_search,params_hash)
6
- query = ""
39
+ query = []
40
+ query_params = []
41
+ params_hash.each do |key,val|
42
+ if !val.empty?
43
+ #key = key.to_s
44
+ key_suffix = key[key.size-3,key.size]
45
+ if key_suffix == "ool"
46
+ if val == "1"
47
+ query.push("#{key[0,key.size-5]} = ?") # excludes 'bool'
48
+ query_params.push(true)
49
+ #else
50
+ # query.push("#{key[0,key.size-5]} = ?") # excludes 'bool'
51
+ # query_params.push(false)
52
+ end
53
+ elsif key_suffix == "min"
54
+ query.push("#{key[0,key.size-4]} >= ?") # excludes 'min'
55
+ query_params.push(val.to_s)
56
+ elsif key_suffix == "max"
57
+ query.push("#{key[0,key.size-4]} <= ?") # excludes 'max'
58
+ query_params.push(val.to_s)
59
+ elsif key_suffix == "_id"
60
+ query.push("#{key} = ?")
61
+ query_params.push(val.to_s)
62
+ else
63
+ query.push("#{key} LIKE ?") # percent sign matches any string of 0 or more chars.
64
+ query_params.push(val + "%")
65
+ end
66
+ end
67
+ end
68
+ if !query.empty?
69
+ if query.size == 1
70
+ return model_to_search.where(query.pop(), query_params.pop())
71
+ else
72
+ prioritized = Glasses.prioritize_ints_over_strings(query, query_params)
73
+ query = prioritized[0]
74
+ query_params = prioritized[1]
75
+ results = model_to_search.where(query.pop(), query_params.pop())
76
+ (query.size).times do |search|
77
+ results = results.where(query.pop(), query_params.pop()) # important to note that ".where()" is not hitting the database on this line.
78
+ end
79
+ return results
80
+ end
81
+ else
82
+ []
83
+ end
84
+ end
85
+
86
+ def self.full_search(model_to_search,params_hash)
87
+ query = []
88
+ query_params = []
7
89
  params_hash.each do |key,val|
8
90
  if !val.empty?
9
91
  if key.to_s[key.size-3,key.size] == "_id"
92
+ query.push("#{key} = ?")
93
+ query_params.push(val.to_s)
94
+ else
95
+ query.push("#{key} LIKE ?") # percent sign matches any string of 0 or more chars.
96
+ query_params.push("%" + val + "%")
97
+ end
98
+ end
99
+ end
100
+ if !query.empty?
101
+ if query.size == 1
102
+ return model_to_search.where(query.pop(), query_params.pop())
103
+ else
104
+ results = model_to_search.where(query.pop(), query_params.pop())
105
+ (query.size).times do |search|
106
+ results = results.where(query.pop(), query_params.pop()) # important to note that ".where()" is not hitting the database on this line.
107
+ end
108
+ return results
109
+ end
110
+ else
111
+ []
112
+ end
113
+ end
114
+
115
+ def self.search_range(model_to_search,params_hash)
116
+ query = []
117
+ query_params = []
118
+ params_hash.each do |key,val|
119
+ if !val.empty?
120
+ #key = key.to_s
121
+ key_suffix = key[key.size-3,key.size]
122
+ if key_suffix == "ool"
123
+ if val == "1"
124
+ query.push("#{key[0,key.size-5]} = ?") # excludes 'bool'
125
+ query_params.push(true)
126
+ #else
127
+ # query.push("#{key[0,key.size-5]} = ?") # excludes 'bool'
128
+ # query_params.push(false)
129
+ end
130
+ elsif key_suffix == "min"
131
+ query.push("#{key[0,key.size-4]} >= ?")
132
+ query_params.push(val.to_s)
133
+ elsif key_suffix == "max"
134
+ query.push("#{key[0,key.size-4]} <= ?")
135
+ query_params.push(val.to_s)
136
+ elsif key_suffix == "_id"
137
+ query.push("#{key} = ?")
138
+ query_params.push(val.to_s)
139
+ else
140
+ query.push("#{key} LIKE ?") # percent sign matches any string of 0 or more chars.
141
+ query_params.push(val + "%")
142
+ end
143
+ end
144
+ end
145
+ if !query.empty?
146
+ if query.size == 1
147
+ return model_to_search.where(query.pop(), query_params.pop())
148
+ else
149
+ prioritized = Glasses.prioritize_ints_over_strings_and_ranges(query, query_params)
150
+ query = prioritized[0]
151
+ query_params = prioritized[1]
152
+ results = model_to_search.where(query.pop(), query_params.pop())
153
+ (query.size).times do |search|
154
+ results = results.where(query.pop(), query_params.pop()) # important to note that ".where()" is not hitting the database on this line.
155
+ end
156
+ return results
157
+ end
158
+ else
159
+ []
160
+ end
161
+ end
162
+
163
+ def self.full_search_range(model_to_search, params_hash)
164
+ query = []
165
+ query_params = []
166
+ params_hash.each do |key,val|
167
+ if !val.empty?
168
+ key_suffix = key.to_s[key.size-3,key.size]
169
+ if key_suffix == "min"
170
+ query.push("#{key[0,key.size-4]} >= ?")
171
+ query_params.push(val.to_s)
172
+ elsif key_suffix == "max"
173
+ query.push("#{key[0,key.size-4]} <= ?")
174
+ query_params.push(val.to_s)
175
+ elsif key_suffix == "_id"
176
+ query.push("#{key} = ?")
177
+ query_params.push(val.to_s)
178
+ else
179
+ query.push("#{key} LIKE ?") # percent sign matches any string of 0 or more chars.
180
+ query_params.push("%" + val + "%")
181
+ end
182
+ end
183
+ end
184
+ if !query.empty?
185
+ if query.size == 1
186
+ return model_to_search.where(query.pop(), query_params.pop())
187
+ else
188
+ prioritized = Glasses.prioritize_ints_over_strings_and_ranges(query, query_params)
189
+ query = prioritized[0]
190
+ query_params = prioritized[1]
191
+ results = model_to_search.where(query.pop(), query_params.pop())
192
+ (query.size).times do |search|
193
+ results = results.where(query.pop(), query_params.pop()) # important to note that ".where()" is not hitting the database on this line.
194
+ end
195
+ return results
196
+ end
197
+ else
198
+ []
199
+ end
200
+ end
201
+
202
+ def self.raw_search(model_to_search,params_hash)
203
+ query = ""
204
+ params_hash.each do |key,val|
205
+ if val
206
+ key = key.to_s
207
+ key_suffix = key.to_s[key.size-3,key.size]
208
+ if key_suffix == "ool"
209
+ query += "#{key[0,key.size-5]} = '1' AND "
210
+ elsif key_suffix == "_id"
10
211
  query += "#{key} = #{val} AND "
11
212
  else
12
213
  query += "#{key} LIKE '#{val}%' AND " # percent sign matches any string of 0 or more chars.
@@ -21,25 +222,68 @@ module Glasses
21
222
  end
22
223
  end
23
224
 
24
- def self.sanitized_search(model_to_search,params_hash)
225
+ def self.full_raw_search(model_to_search,params_hash)
25
226
  query = ""
26
- query_params = []
27
227
  params_hash.each do |key,val|
28
228
  if !val.empty?
29
229
  if key.to_s[key.size-3,key.size] == "_id"
30
- query += "#{key} = ? AND "
31
- query_params.push(val.to_s)
230
+ query += "#{key} = #{val} AND "
32
231
  else
33
- query += "#{key} LIKE ? AND " # percent sign matches any string of 0 or more chars.
34
- query_params.push(val + "%")
232
+ query += "#{key} LIKE '%#{val}%' AND " # percent sign matches any string of 0 or more chars.
35
233
  end
36
234
  end
37
235
  end
38
236
  if !query.empty?
39
237
  query = query[0,query.size-5]
40
- #model_to_search.where(ActiveRecord::Base::sanitize(query)) # sanitize_sql() is an Alias for ActiveRecord::Sanitization::ClassMethods#sanitize_sql_for_conditions .
41
- # Requires rails version 3.2.1 or higher.
42
- model_to_search.where(query, query_params)
238
+ model_to_search.where(query)
239
+ else
240
+ []
241
+ end
242
+ end
243
+
244
+ def self.raw_search_range(model_to_search,params_hash)
245
+ query = ""
246
+ params_hash.each do |key,val|
247
+ if !val.empty?
248
+ key_suffix = key.to_s[key.size-3,key.size]
249
+ if key_suffix == "min"
250
+ query += "#{key[0,key.size-4]} >= #{val} AND "
251
+ elsif key_suffix == "max"
252
+ query += "#{key[0,key.size-4]} <= #{val} AND "
253
+ elsif key_suffix == "_id"
254
+ query += "#{key} = #{val} AND "
255
+ else
256
+ query += "#{key} LIKE '#{val}%' AND " # percent sign matches any string of 0 or more chars.
257
+ end
258
+ end
259
+ end
260
+ if !query.empty?
261
+ query = query[0,query.size-5]
262
+ model_to_search.where(query)
263
+ else
264
+ []
265
+ end
266
+ end
267
+
268
+ def self.full_raw_search_range(model_to_search, params_hash)
269
+ query = ""
270
+ params_hash.each do |key,val|
271
+ if !val.empty?
272
+ key_suffix = key.to_s[key.size-3,key.size]
273
+ if key_suffix == "min"
274
+ query += "#{key[0,key.size-4]} >= #{val} AND "
275
+ elsif key_suffix == "max"
276
+ query += "#{key[0,key.size-4]} <= #{val} AND "
277
+ elsif key_suffix == "_id"
278
+ query += "#{key} = #{val} AND "
279
+ else
280
+ query += "#{key} LIKE '%#{val}%' AND " # percent sign matches any string of 0 or more chars.
281
+ end
282
+ end
283
+ end
284
+ if !query.empty?
285
+ query = query[0,query.size-5]
286
+ model_to_search.where(query)
43
287
  else
44
288
  []
45
289
  end
@@ -1,3 +1,3 @@
1
1
  module Glasses
2
- VERSION = "1.6.2"
2
+ VERSION = "1.7.0"
3
3
  end
@@ -16,7 +16,7 @@ class SearchController < ApplicationController
16
16
 
17
17
  def method_sanitized_simple_search
18
18
  if params[:search_params]
19
- @players = Glasses.sanitized_search(Player, params[:search_params])
19
+ @players = Glasses.raw_search(Player, params[:search_params])
20
20
  @num_results = 0
21
21
  else
22
22
  @players = []
@@ -40,17 +40,36 @@ class SearchController < ApplicationController
40
40
  end
41
41
  end
42
42
 
43
+ def range_search
44
+ if params[:search_params]
45
+ @players = Glasses.search_range(Player, params[:search_params])
46
+ @num_results = 0
47
+ else
48
+ @players = []
49
+ end
50
+ end
51
+
52
+ def raw_range_search
53
+ if params[:search_params]
54
+ @players = Glasses.raw_search_range(Player, params[:search_params])
55
+ @num_results = 0
56
+ else
57
+ @players = []
58
+ end
59
+ end
60
+
61
+ def full_search_range
62
+
63
+ end
64
+
43
65
  protected
44
66
 
45
67
  def search_params_sanitizer_defined_in_the_app(search_params, escape_char = "\\")
46
68
  sanitized_params = {}
47
- pattern = Regexp.union(escape_char, "%", "_", "--", "=")
48
- search_params.each do |key, val|
49
- #sanitized_params[key] = ActiveRecord::Base.sanitize(val)
50
- #sanitized_params[key] = val
51
- sanitized_params[key] = val.gsub(pattern) do |s|
52
- [escape_char, s].join
53
- end
69
+ pattern = Regexp.union(escape_char, "%", "_", "=")
70
+ search_params.each do |key, val|
71
+ # sanitizing data directly is not that a good idea and should be done when no other solution is available
72
+ sanitized_params[key] = val.gsub(/\\/, '\&\&').gsub(/'/, "''")
54
73
  end
55
74
  begin
56
75
  return sanitized_params
@@ -60,16 +79,9 @@ class SearchController < ApplicationController
60
79
  end
61
80
 
62
81
  def caughts_injected_code_in_search(search_params, escape_char = "\\")
63
- sanitized_params = {}
64
- pattern = Regexp.union(escape_char, "%", "_", "--", "=")
65
- search_params.each do |key, val|
66
- sanitized_params[key] = val.gsub(pattern) do |s|
67
- [escape_char, s].join
68
- end
69
- end
70
-
82
+ sanitized_params = search_params_sanitizer_defined_in_the_app(search_params, escape_char = "\\")
71
83
  begin
72
- results = Glasses.search(Player, sanitized_params)
84
+ results = Glasses.raw_search(Player, sanitized_params)
73
85
  rescue SQLException
74
86
  results = []
75
87
  end
@@ -0,0 +1,30 @@
1
+ <%= form_for(:search_params, url: range_search_path, method: "get", id: "simple_search_form") do |f| %>
2
+
3
+ <%= f.label :first_name, "First Name:" %>
4
+ <%= f.text_field :first_name %>
5
+
6
+ <%= f.label :age_min, "Minimum Age:" %>
7
+ <%= f.text_field :age_min %>
8
+
9
+ <%= f.label :age_max, "Maximum Age:" %>
10
+ <%= f.text_field :age_max %>
11
+
12
+ <label>Looking for a virgin loser:
13
+ <input name="search_params[is_virgin_bool]" type="hidden" value="0" />
14
+ <input checked="checked" type="checkbox" id="checked_box" name="search_params[is_virgin_bool]" value="1" />
15
+ </label>
16
+
17
+ <%= f.submit "Search" %>
18
+ <% end %>
19
+
20
+ <% if @players.empty? %>
21
+ <p id="fail">WOPS, NOTHING TO SEARCH</p>
22
+ <p>0 entries</p>
23
+ <% else %>
24
+
25
+ <% @players.each do |p| %>
26
+ <% @num_results += 1 %>
27
+ <p id="success"><%= p.first_name %>, GR8 SUCCESS</p>
28
+ <% end %>
29
+ <p><%= "#{@num_results}"%></p>
30
+ <% end %>
@@ -0,0 +1,25 @@
1
+ <%= form_for(:search_params, url: raw_range_search_path, method: "get", id: "simple_search_form") do |f| %>
2
+
3
+ <%= f.label :first_name, "First Name:" %>
4
+ <%= f.text_field :first_name %>
5
+
6
+ <%= f.label :age_min, "Minimum Age:" %>
7
+ <%= f.text_field :age_min %>
8
+
9
+ <%= f.label :age_max, "Maximum Age:" %>
10
+ <%= f.text_field :age_max %>
11
+
12
+ <%= f.submit "Search" %>
13
+ <% end %>
14
+
15
+ <% if @players.empty? %>
16
+ <p id="fail">WOPS, NOTHING TO SEARCH</p>
17
+ <p>0 entries</p>
18
+ <% else %>
19
+
20
+ <% @players.each do |p| %>
21
+ <% @num_results += 1 %>
22
+ <p id="success"><%= p.first_name %>, GR8 SUCCESS</p>
23
+ <% end %>
24
+ <p><%= "#{@num_results}"%></p>
25
+ <% end %>
@@ -3,6 +3,9 @@
3
3
  <%= f.label :first_name, "First Name:" %>
4
4
  <%= f.text_field :first_name %>
5
5
 
6
+ <label>Looking for a virgin loser:
7
+ <input checked="checked" type="checkbox" id="checked_box" name="search_params[is_virgin_bool]" value="1" />
8
+ </label>
6
9
  <%= f.submit "Search" %>
7
10
  <% end %>
8
11
 
@@ -10,10 +13,9 @@
10
13
  <p id="fail">WOPS, NOTHING TO SEARCH</p>
11
14
  <p>0 entries</p>
12
15
  <% else %>
13
-
14
16
  <% @players.each do |p| %>
15
17
  <% @num_results += 1 %>
16
- <p id="success"><%= p.first_name %>, GR8 SUCCESS</p>
18
+ <p id="success"><%= p.first_name %>,<%= p.is_virgin.to_s %>,<%= "LOOOSERR," if p.is_virgin %> GR8 SUCCESS</p>
17
19
  <% end %>
18
20
  <p><%= "#{@num_results}"%> entries</p>
19
21
  <% end %>