action_query 0.1.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 169707c8efdb0a8cd829ee5cd1e7c1f681259228
4
- data.tar.gz: a1176eae268e54fdefd2077c97e1122d3576f6e7
3
+ metadata.gz: 96917fcf22ad5aa27ddcbf7f87e6883b3c6bd23b
4
+ data.tar.gz: fe95850d9a5896d34f3b9bc87be8f226d1a83067
5
5
  SHA512:
6
- metadata.gz: 44e385ce0fe32db644ceab187f8e16e0dc671a34f4afd084e8ebb36c2859437c3d83fcaa14a63283ab2bcdef24246de401d60f15da9175c3cf86ca03e360fb17
7
- data.tar.gz: dc16eff32feea054ae6fb419e7fb9ad4284c7733c2571b1df1bdfaef963ddb1c313a9758d3e179be3da3e6c8cacaff1b1e9f53616d5887cb57ba1f93dddf60af
6
+ metadata.gz: 6f13ad6bb35ea05f661e16ea6349c221b65db8e94a82e416e1950b76fc709daeab929b369de1119e6c517b3f968b3ad351f13e3be69f4103b36f8e71851221ae
7
+ data.tar.gz: b95f69ee1117ee95fdf546cc53c1a282d50d13fec2bd466bd97df77f395913b995482957fa50c635ac533f9d657fe89b8396574049473067ac41506d2462185e
data/.ruby-gemset ADDED
@@ -0,0 +1 @@
1
+ action_query
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ ruby-2.4.0
@@ -0,0 +1,49 @@
1
+ module ActionQuery
2
+ module Route
3
+ def self.result
4
+ controllers = HashWithIndifferentAccess.new
5
+ ::Rails.application.routes.routes.each do |route|
6
+ next unless route.defaults[:controller]
7
+ names = route.defaults[:controller].split('/')
8
+ obj = controllers
9
+ names.each_with_index do |name,index|
10
+ obj[name.classify()] ||= HashWithIndifferentAccess.new
11
+ obj = obj[name.classify()]
12
+ end
13
+ obj[route.defaults[:action]] ||= []
14
+ path = {
15
+ parts: route.parts.map(&:to_s),
16
+ path: route.path.spec.to_s,
17
+ verb: route.verb,
18
+ requirements: route.required_parts.map(&:to_s),
19
+ method: route.defaults[:action]
20
+ }
21
+ obj[route.defaults[:action]] << path
22
+ end
23
+ controllers
24
+ end
25
+
26
+ def self.to_coffee
27
+ result.map{|k,v| self.write_class("#{k}",v)}.flatten.join
28
+ end
29
+
30
+
31
+ def self.write_class(key,val)
32
+ classes = []
33
+ res = "class ActionQuery.#{key} extends ActionQuery.$Base\n"
34
+ res += " @methods("
35
+ arr = []
36
+ val.each do |k,v|
37
+ if v.is_a? Array
38
+ arr << "#{k}: [{#{v.map{|path| path.map{|l,m| "#{l}: #{m.inspect}"}.join(',')}.join('},{')}}]"
39
+ else
40
+ classes << write_class("#{key}.#{k}",v)
41
+ end
42
+ end
43
+ res += arr.join(',')
44
+ res += " )\n"
45
+ [res] | classes
46
+ end
47
+
48
+ end
49
+ end
@@ -1,3 +1,3 @@
1
1
  module ActionQuery
2
- VERSION = "0.1.0"
2
+ VERSION = "0.5.0"
3
3
  end
data/lib/action_query.rb CHANGED
@@ -1,5 +1,9 @@
1
1
  require "action_query/version"
2
+ require "action_query/route"
2
3
 
3
4
  module ActionQuery
4
- # Your code goes here...
5
+ module Rails
6
+ class Engine < ::Rails::Engine
7
+ end
8
+ end
5
9
  end
@@ -0,0 +1,13 @@
1
+ # //= require_tree ./extensions
2
+ # //= require action_query/class_methods
3
+ # //= require action_query/private_methods
4
+ @ActionQuery ?= {}
5
+ class ActionQuery.$Base extends Module
6
+ @extend(ActionQuery.$ClassMethods)
7
+ @include(ActionQuery.$PrivateMethods)
8
+ $save: ->
9
+ # Only trigger save after last action completed (can't create until new is done)
10
+ # (can't update until create or update is done)
11
+ @$promise.then @__save__.bind(@)
12
+ $destroy: ->
13
+ @$promise.then @__destroy__.bind(@)
@@ -0,0 +1,36 @@
1
+ @ActionQuery ?= {}
2
+ class @ActionQuery.$ClassMethods
3
+ methods: (args) ->
4
+ @_createMethod(name,details) for name,details of args
5
+ _createMethod: (name,details) ->
6
+ @::__routes__ ||= []
7
+ @::__routes__.merge(details)
8
+ @[name] = (params) ->
9
+ params = {id: params} if !isNaN(params)
10
+ params ||= {}
11
+ params.format ||= 'json'
12
+ paths = []
13
+ for route in details
14
+ continue unless route.requirements.subtract(Object.keys(params)).length == 0
15
+ path = route.path
16
+ for key,val of params
17
+ path = path.replace(":#{key}",val)
18
+ path = path.replace /\(.*\)/, (match) ->
19
+ return '' if match.indexOf(':') >= 0
20
+ return match[1..-2]
21
+ paths.push(weight: route.requirements.length, path: path, verb: route.verb)
22
+ weight = paths.pluck('weight').max()
23
+ path = (paths.filter (path) -> path.weight == weight).first()
24
+ @_sendRequest(path,params)
25
+
26
+ _sendRequest: (details,params) ->
27
+ data = {}
28
+ data[@name.underscore()] = params
29
+ newRec = new @
30
+ newRec.$promise = $.ajax(
31
+ url: details.path
32
+ method: details.verb
33
+ data: data
34
+ )
35
+ .then newRec.__processResponse__.bind(newRec)
36
+ return newRec
@@ -0,0 +1,2 @@
1
+ # //= require action_query/base
2
+ <%= ActionQuery::Route.to_coffee %>
@@ -0,0 +1,46 @@
1
+ unless Array::includes
2
+ Array::includes = (el) -> @indexOf(el) >= 0
3
+ unless Array::filter
4
+ Array::filter = (fn) ->
5
+ arr = []
6
+ (arr.push(el) if fn(el)) for el in @
7
+ unless Array::intersection
8
+ Array::intersection = (arr) ->
9
+ @filter((el) -> arr.includes(el))
10
+ unless Array::intersects
11
+ Array::intersects = (arr) ->
12
+ @intersection(arr).length > 0
13
+ unless Array::subtract
14
+ Array::subtract = (arr) ->
15
+ @filter((el) -> !arr.includes(el))
16
+ unless Array::pluck
17
+ Array::pluck = (keys...) ->
18
+ keys = keys.flatten()
19
+ arr = []
20
+ for el in @
21
+ arr.push(keys.map (key) -> el[key])
22
+ return if keys.length == 1 then arr.flatten() else arr
23
+ unless Array::flatten
24
+ Array::flatten = ->
25
+ arr = []
26
+ for l in @
27
+ if Array.isArray(l)
28
+ for i in l.flatten()
29
+ arr.push i
30
+ else
31
+ arr.push l
32
+ arr
33
+ unless Array::min
34
+ Array::min = -> return Math.min.apply(null,@)
35
+ Array::max = -> return Math.max.apply(null,@)
36
+ unless Array::first
37
+ Array::first = -> @[0]
38
+ Array::last = -> @[@length - 1]
39
+ unless Array::dup
40
+ Array::dup = -> return @slice(0)
41
+ Array::empty = -> @length == 0
42
+ Array::present = -> @length != 0
43
+ unless Array::merge
44
+ Array::merge = (arr) ->
45
+ @push(el) for el in arr
46
+ @
@@ -0,0 +1,637 @@
1
+ /*
2
+ Copyright (c) 2007-2015 Ryan Schuft (ryan.schuft@gmail.com)
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+ The above copyright notice and this permission notice shall be included in
10
+ all copies or substantial portions of the Software.
11
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
12
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
14
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
15
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
16
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
17
+ THE SOFTWARE.
18
+ */
19
+
20
+ /*
21
+ This code is based in part on the work done in Ruby to support
22
+ infection as part of Ruby on Rails in the ActiveSupport's Inflector
23
+ and Inflections classes. It was initally ported to Javascript by
24
+ Ryan Schuft (ryan.schuft@gmail.com) in 2007.
25
+ The code is available at http://code.google.com/p/inflection-js/
26
+ The basic usage is:
27
+ 1. Include this script on your web page.
28
+ 2. Call functions on any String object in Javascript
29
+ Currently implemented functions:
30
+ String.pluralize(plural) == String
31
+ renders a singular English language noun into its plural form
32
+ normal results can be overridden by passing in an alternative
33
+ String.singularize(singular) == String
34
+ renders a plural English language noun into its singular form
35
+ normal results can be overridden by passing in an alterative
36
+ String.camelize(lowFirstLetter) == String
37
+ renders a lower case underscored word into camel case
38
+ the first letter of the result will be upper case unless you pass true
39
+ also translates "/" into "::" (underscore does the opposite)
40
+ String.underscore() == String
41
+ renders a camel cased word into words seperated by underscores
42
+ also translates "::" back into "/" (camelize does the opposite)
43
+ String.humanize(lowFirstLetter) == String
44
+ renders a lower case and underscored word into human readable form
45
+ defaults to making the first letter capitalized unless you pass true
46
+ String.capitalize() == String
47
+ renders all characters to lower case and then makes the first upper
48
+ String.dasherize() == String
49
+ renders all underbars and spaces as dashes
50
+ String.titleize() == String
51
+ renders words into title casing (as for book titles)
52
+ String.demodulize() == String
53
+ renders class names that are prepended by modules into just the class
54
+ String.tableize() == String
55
+ renders camel cased singular words into their underscored plural form
56
+ String.classify() == String
57
+ renders an underscored plural word into its camel cased singular form
58
+ String.foreign_key(dropIdUbar) == String
59
+ renders a class name (camel cased singular noun) into a foreign key
60
+ defaults to seperating the class from the id with an underbar unless
61
+ you pass true
62
+ String.ordinalize() == String
63
+ renders all numbers found in the string into their sequence like "22nd"
64
+ */
65
+
66
+ /*
67
+ This sets up a container for some constants in its own namespace
68
+ We use the window (if available) to enable dynamic loading of this script
69
+ Window won't necessarily exist for non-browsers.
70
+ */
71
+ if (typeof window !== "undefined" && !window.InflectionJS)
72
+ {
73
+ window.InflectionJS = null;
74
+ }
75
+
76
+ /*
77
+ This sets up some constants for later use
78
+ This should use the window namespace variable if available
79
+ */
80
+ InflectionJS =
81
+ {
82
+ /*
83
+ This is a list of nouns that use the same form for both singular and plural.
84
+ This list should remain entirely in lower case to correctly match Strings.
85
+ */
86
+ uncountable_words: [
87
+ 'equipment', 'information', 'rice', 'money', 'species', 'series',
88
+ 'fish', 'sheep', 'moose', 'deer', 'news'
89
+ ],
90
+
91
+ /*
92
+ These rules translate from the singular form of a noun to its plural form.
93
+ */
94
+ plural_rules: [
95
+ [new RegExp('(m)an$', 'gi'), '$1en'],
96
+ [new RegExp('(pe)rson$', 'gi'), '$1ople'],
97
+ [new RegExp('(child)$', 'gi'), '$1ren'],
98
+ [new RegExp('^(ox)$', 'gi'), '$1en'],
99
+ [new RegExp('(ax|test)is$', 'gi'), '$1es'],
100
+ [new RegExp('(octop|vir)us$', 'gi'), '$1i'],
101
+ [new RegExp('(alias|status)$', 'gi'), '$1es'],
102
+ [new RegExp('(bu)s$', 'gi'), '$1ses'],
103
+ [new RegExp('(buffal|tomat|potat)o$', 'gi'), '$1oes'],
104
+ [new RegExp('([ti])um$', 'gi'), '$1a'],
105
+ [new RegExp('sis$', 'gi'), 'ses'],
106
+ [new RegExp('(?:([^f])fe|([lr])f)$', 'gi'), '$1$2ves'],
107
+ [new RegExp('(hive)$', 'gi'), '$1s'],
108
+ [new RegExp('([^aeiouy]|qu)y$', 'gi'), '$1ies'],
109
+ [new RegExp('(x|ch|ss|sh)$', 'gi'), '$1es'],
110
+ [new RegExp('(matr|vert|ind)ix|ex$', 'gi'), '$1ices'],
111
+ [new RegExp('([m|l])ouse$', 'gi'), '$1ice'],
112
+ [new RegExp('(quiz)$', 'gi'), '$1zes'],
113
+ [new RegExp('s$', 'gi'), 's'],
114
+ [new RegExp('$', 'gi'), 's']
115
+ ],
116
+
117
+ /*
118
+ These rules translate from the plural form of a noun to its singular form.
119
+ */
120
+ singular_rules: [
121
+ [new RegExp('(m)en$', 'gi'), '$1an'],
122
+ [new RegExp('(pe)ople$', 'gi'), '$1rson'],
123
+ [new RegExp('(child)ren$', 'gi'), '$1'],
124
+ [new RegExp('([ti])a$', 'gi'), '$1um'],
125
+ [new RegExp('((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$','gi'), '$1$2sis'],
126
+ [new RegExp('(hive)s$', 'gi'), '$1'],
127
+ [new RegExp('(tive)s$', 'gi'), '$1'],
128
+ [new RegExp('(curve)s$', 'gi'), '$1'],
129
+ [new RegExp('([lr])ves$', 'gi'), '$1f'],
130
+ [new RegExp('([^fo])ves$', 'gi'), '$1fe'],
131
+ [new RegExp('([^aeiouy]|qu)ies$', 'gi'), '$1y'],
132
+ [new RegExp('(s)eries$', 'gi'), '$1eries'],
133
+ [new RegExp('(m)ovies$', 'gi'), '$1ovie'],
134
+ [new RegExp('(x|ch|ss|sh)es$', 'gi'), '$1'],
135
+ [new RegExp('([m|l])ice$', 'gi'), '$1ouse'],
136
+ [new RegExp('(bus)es$', 'gi'), '$1'],
137
+ [new RegExp('(o)es$', 'gi'), '$1'],
138
+ [new RegExp('(shoe)s$', 'gi'), '$1'],
139
+ [new RegExp('(cris|ax|test)es$', 'gi'), '$1is'],
140
+ [new RegExp('(octop|vir)i$', 'gi'), '$1us'],
141
+ [new RegExp('(alias|status)es$', 'gi'), '$1'],
142
+ [new RegExp('^(ox)en', 'gi'), '$1'],
143
+ [new RegExp('(vert|ind)ices$', 'gi'), '$1ex'],
144
+ [new RegExp('(matr)ices$', 'gi'), '$1ix'],
145
+ [new RegExp('(quiz)zes$', 'gi'), '$1'],
146
+ [new RegExp('s$', 'gi'), '']
147
+ ],
148
+
149
+ /*
150
+ This is a list of words that should not be capitalized for title case
151
+ */
152
+ non_titlecased_words: [
153
+ 'and', 'or', 'nor', 'a', 'an', 'the', 'so', 'but', 'to', 'of', 'at',
154
+ 'by', 'from', 'into', 'on', 'onto', 'off', 'out', 'in', 'over',
155
+ 'with', 'for'
156
+ ],
157
+
158
+ /*
159
+ These are regular expressions used for converting between String formats
160
+ */
161
+ id_suffix: new RegExp('(_ids|_id)$', 'g'),
162
+ underbar: new RegExp('_', 'g'),
163
+ space_or_underbar: new RegExp('[\ _]', 'g'),
164
+ uppercase: new RegExp('([A-Z])', 'g'),
165
+ underbar_prefix: new RegExp('^_'),
166
+
167
+ /*
168
+ This is a helper method that applies rules based replacement to a String
169
+ Signature:
170
+ InflectionJS.apply_rules(str, rules, skip, override) == String
171
+ Arguments:
172
+ str - String - String to modify and return based on the passed rules
173
+ rules - Array: [RegExp, String] - Regexp to match paired with String to use for replacement
174
+ skip - Array: [String] - Strings to skip if they match
175
+ override - String (optional) - String to return as though this method succeeded (used to conform to APIs)
176
+ Returns:
177
+ String - passed String modified by passed rules
178
+ Examples:
179
+ InflectionJS.apply_rules("cows", InflectionJs.singular_rules) === 'cow'
180
+ */
181
+ apply_rules: function(str, rules, skip, override)
182
+ {
183
+ if (override)
184
+ {
185
+ str = override;
186
+ }
187
+ else
188
+ {
189
+ var ignore = (skip.indexOf(str.toLowerCase()) > -1);
190
+ if (!ignore)
191
+ {
192
+ for (var x = 0; x < rules.length; x++)
193
+ {
194
+ if (str.match(rules[x][0]))
195
+ {
196
+ str = str.replace(rules[x][0], rules[x][1]);
197
+ break;
198
+ }
199
+ }
200
+ }
201
+ }
202
+ return '' + str;
203
+ }
204
+ };
205
+
206
+ /*
207
+ This lets us detect if an Array contains a given element
208
+ Signature:
209
+ Array.indexOf(item, fromIndex, compareFunc) == Integer
210
+ Arguments:
211
+ item - Object - object to locate in the Array
212
+ fromIndex - Integer (optional) - starts checking from this position in the Array
213
+ compareFunc - Function (optional) - function used to compare Array item vs passed item
214
+ Returns:
215
+ Integer - index position in the Array of the passed item
216
+ Examples:
217
+ ['hi','there'].indexOf("guys") === -1
218
+ ['hi','there'].indexOf("hi") === 0
219
+ */
220
+ if (!Array.prototype.indexOf)
221
+ {
222
+ Array.prototype.indexOf = function(item, fromIndex, compareFunc)
223
+ {
224
+ if (!fromIndex)
225
+ {
226
+ fromIndex = -1;
227
+ }
228
+ var index = -1;
229
+ for (var i = fromIndex; i < this.length; i++)
230
+ {
231
+ if (this[i] === item || compareFunc && compareFunc(this[i], item))
232
+ {
233
+ index = i;
234
+ break;
235
+ }
236
+ }
237
+ return index;
238
+ };
239
+ }
240
+
241
+ /*
242
+ You can override this list for all Strings or just one depending on if you
243
+ set the new values on prototype or on a given String instance.
244
+ */
245
+ if (!String.prototype._uncountable_words)
246
+ {
247
+ String.prototype._uncountable_words = InflectionJS.uncountable_words;
248
+ }
249
+
250
+ /*
251
+ You can override this list for all Strings or just one depending on if you
252
+ set the new values on prototype or on a given String instance.
253
+ */
254
+ if (!String.prototype._plural_rules)
255
+ {
256
+ String.prototype._plural_rules = InflectionJS.plural_rules;
257
+ }
258
+
259
+ /*
260
+ You can override this list for all Strings or just one depending on if you
261
+ set the new values on prototype or on a given String instance.
262
+ */
263
+ if (!String.prototype._singular_rules)
264
+ {
265
+ String.prototype._singular_rules = InflectionJS.singular_rules;
266
+ }
267
+
268
+ /*
269
+ You can override this list for all Strings or just one depending on if you
270
+ set the new values on prototype or on a given String instance.
271
+ */
272
+ if (!String.prototype._non_titlecased_words)
273
+ {
274
+ String.prototype._non_titlecased_words = InflectionJS.non_titlecased_words;
275
+ }
276
+
277
+ /*
278
+ This function adds plurilization support to every String object
279
+ Signature:
280
+ String.pluralize(plural) == String
281
+ Arguments:
282
+ plural - String (optional) - overrides normal output with said String
283
+ Returns:
284
+ String - singular English language nouns are returned in plural form
285
+ Examples:
286
+ "person".pluralize() == "people"
287
+ "octopus".pluralize() == "octopi"
288
+ "Hat".pluralize() == "Hats"
289
+ "person".pluralize("guys") == "guys"
290
+ */
291
+ if (!String.prototype.pluralize)
292
+ {
293
+ String.prototype.pluralize = function(plural)
294
+ {
295
+ return InflectionJS.apply_rules(
296
+ this,
297
+ this._plural_rules,
298
+ this._uncountable_words,
299
+ plural
300
+ );
301
+ };
302
+ }
303
+
304
+ /*
305
+ This function adds singularization support to every String object
306
+ Signature:
307
+ String.singularize(singular) == String
308
+ Arguments:
309
+ singular - String (optional) - overrides normal output with said String
310
+ Returns:
311
+ String - plural English language nouns are returned in singular form
312
+ Examples:
313
+ "people".singularize() == "person"
314
+ "octopi".singularize() == "octopus"
315
+ "Hats".singularize() == "Hat"
316
+ "guys".singularize("person") == "person"
317
+ */
318
+ if (!String.prototype.singularize)
319
+ {
320
+ String.prototype.singularize = function(singular)
321
+ {
322
+ return InflectionJS.apply_rules(
323
+ this,
324
+ this._singular_rules,
325
+ this._uncountable_words,
326
+ singular
327
+ );
328
+ };
329
+ }
330
+
331
+ /*
332
+ This function adds camelization support to every String object
333
+ Signature:
334
+ String.camelize(lowFirstLetter) == String
335
+ Arguments:
336
+ lowFirstLetter - boolean (optional) - default is to capitalize the first
337
+ letter of the results... passing true will lowercase it
338
+ Returns:
339
+ String - lower case underscored words will be returned in camel case
340
+ additionally '/' is translated to '::'
341
+ Examples:
342
+ "message_properties".camelize() == "MessageProperties"
343
+ "message_properties".camelize(true) == "messageProperties"
344
+ */
345
+ if (!String.prototype.camelize)
346
+ {
347
+ String.prototype.camelize = function(lowFirstLetter)
348
+ {
349
+ var str = this.toLowerCase();
350
+ var str_path = str.split('/');
351
+ for (var i = 0; i < str_path.length; i++)
352
+ {
353
+ var str_arr = str_path[i].split('_');
354
+ var initX = ((lowFirstLetter && i + 1 === str_path.length) ? (1) : (0));
355
+ for (var x = initX; x < str_arr.length; x++)
356
+ {
357
+ str_arr[x] = str_arr[x].charAt(0).toUpperCase() + str_arr[x].substring(1);
358
+ }
359
+ str_path[i] = str_arr.join('');
360
+ }
361
+ str = str_path.join('::');
362
+ return '' + str;
363
+ };
364
+ }
365
+
366
+ /*
367
+ This function adds underscore support to every String object
368
+ Signature:
369
+ String.underscore() == String
370
+ Arguments:
371
+ N/A
372
+ Returns:
373
+ String - camel cased words are returned as lower cased and underscored
374
+ additionally '::' is translated to '/'
375
+ Examples:
376
+ "MessageProperties".camelize() == "message_properties"
377
+ "messageProperties".underscore() == "message_properties"
378
+ */
379
+ if (!String.prototype.underscore)
380
+ {
381
+ String.prototype.underscore = function()
382
+ {
383
+ var str = this;
384
+ var str_path = str.split('::');
385
+ for (var i = 0; i < str_path.length; i++)
386
+ {
387
+ str_path[i] = str_path[i].replace(InflectionJS.uppercase, '_$1');
388
+ str_path[i] = str_path[i].replace(InflectionJS.underbar_prefix, '');
389
+ }
390
+ str = str_path.join('/').toLowerCase();
391
+ return '' + str;
392
+ };
393
+ }
394
+
395
+ /*
396
+ This function adds humanize support to every String object
397
+ Signature:
398
+ String.humanize(lowFirstLetter) == String
399
+ Arguments:
400
+ lowFirstLetter - boolean (optional) - default is to capitalize the first
401
+ letter of the results... passing true will lowercase it
402
+ Returns:
403
+ String - lower case underscored words will be returned in humanized form
404
+ Examples:
405
+ "message_properties".humanize() == "Message properties"
406
+ "message_properties".humanize(true) == "message properties"
407
+ */
408
+ if (!String.prototype.humanize)
409
+ {
410
+ String.prototype.humanize = function(lowFirstLetter)
411
+ {
412
+ var str = this.toLowerCase();
413
+ str = str.replace(InflectionJS.id_suffix, '');
414
+ str = str.replace(InflectionJS.underbar, ' ');
415
+ if (!lowFirstLetter)
416
+ {
417
+ str = str.capitalize();
418
+ }
419
+ return '' + str;
420
+ };
421
+ }
422
+
423
+ /*
424
+ This function adds capitalization support to every String object
425
+ Signature:
426
+ String.capitalize() == String
427
+ Arguments:
428
+ N/A
429
+ Returns:
430
+ String - all characters will be lower case and the first will be upper
431
+ Examples:
432
+ "message_properties".capitalize() == "Message_properties"
433
+ "message properties".capitalize() == "Message properties"
434
+ */
435
+ if (!String.prototype.capitalize)
436
+ {
437
+ String.prototype.capitalize = function()
438
+ {
439
+ var str = this.toLowerCase();
440
+ str = str.substring(0, 1).toUpperCase() + str.substring(1);
441
+ return '' + str;
442
+ };
443
+ }
444
+
445
+ /*
446
+ This function adds dasherization support to every String object
447
+ Signature:
448
+ String.dasherize() == String
449
+ Arguments:
450
+ N/A
451
+ Returns:
452
+ String - replaces all spaces or underbars with dashes
453
+ Examples:
454
+ "message_properties".capitalize() == "message-properties"
455
+ "Message Properties".capitalize() == "Message-Properties"
456
+ */
457
+ if (!String.prototype.dasherize)
458
+ {
459
+ String.prototype.dasherize = function()
460
+ {
461
+ var str = this;
462
+ str = str.replace(InflectionJS.space_or_underbar, '-');
463
+ return '' + str;
464
+ };
465
+ }
466
+
467
+ /*
468
+ This function adds titleize support to every String object
469
+ Signature:
470
+ String.titleize() == String
471
+ Arguments:
472
+ N/A
473
+ Returns:
474
+ String - capitalizes words as you would for a book title
475
+ Examples:
476
+ "message_properties".titleize() == "Message Properties"
477
+ "message properties to keep".titleize() == "Message Properties to Keep"
478
+ */
479
+ if (!String.prototype.titleize)
480
+ {
481
+ String.prototype.titleize = function()
482
+ {
483
+ var str = this.toLowerCase();
484
+ str = str.replace(InflectionJS.underbar, ' ');
485
+ var str_arr = str.split(' ');
486
+ for (var x = 0; x < str_arr.length; x++)
487
+ {
488
+ var d = str_arr[x].split('-');
489
+ for (var i = 0; i < d.length; i++)
490
+ {
491
+ if (this._non_titlecased_words.indexOf(d[i].toLowerCase()) < 0)
492
+ {
493
+ d[i] = d[i].capitalize();
494
+ }
495
+ }
496
+ str_arr[x] = d.join('-');
497
+ }
498
+ str = str_arr.join(' ');
499
+ str = str.substring(0, 1).toUpperCase() + str.substring(1);
500
+ return '' + str;
501
+ };
502
+ }
503
+
504
+ /*
505
+ This function adds demodulize support to every String object
506
+ Signature:
507
+ String.demodulize() == String
508
+ Arguments:
509
+ N/A
510
+ Returns:
511
+ String - removes module names leaving only class names (Ruby style)
512
+ Examples:
513
+ "Message::Bus::Properties".demodulize() == "Properties"
514
+ */
515
+ if (!String.prototype.demodulize)
516
+ {
517
+ String.prototype.demodulize = function()
518
+ {
519
+ var str = this;
520
+ var str_arr = str.split('::');
521
+ str = str_arr[str_arr.length - 1];
522
+ return '' + str;
523
+ };
524
+ }
525
+
526
+ /*
527
+ This function adds tableize support to every String object
528
+ Signature:
529
+ String.tableize() == String
530
+ Arguments:
531
+ N/A
532
+ Returns:
533
+ String - renders camel cased words into their underscored plural form
534
+ Examples:
535
+ "MessageBusProperty".tableize() == "message_bus_properties"
536
+ */
537
+ if (!String.prototype.tableize)
538
+ {
539
+ String.prototype.tableize = function()
540
+ {
541
+ var str = this;
542
+ str = str.underscore().pluralize();
543
+ return '' + str;
544
+ };
545
+ }
546
+
547
+ /*
548
+ This function adds classification support to every String object
549
+ Signature:
550
+ String.classify() == String
551
+ Arguments:
552
+ N/A
553
+ Returns:
554
+ String - underscored plural nouns become the camel cased singular form
555
+ Examples:
556
+ "message_bus_properties".classify() == "MessageBusProperty"
557
+ */
558
+ if (!String.prototype.classify)
559
+ {
560
+ String.prototype.classify = function()
561
+ {
562
+ var str = this;
563
+ str = str.camelize().singularize();
564
+ return '' + str;
565
+ };
566
+ }
567
+
568
+ /*
569
+ This function adds foreign key support to every String object
570
+ Signature:
571
+ String.foreign_key(dropIdUbar) == String
572
+ Arguments:
573
+ dropIdUbar - boolean (optional) - default is to seperate id with an
574
+ underbar at the end of the class name, you can pass true to skip it
575
+ Returns:
576
+ String - camel cased singular class names become underscored with id
577
+ Examples:
578
+ "MessageBusProperty".foreign_key() == "message_bus_property_id"
579
+ "MessageBusProperty".foreign_key(true) == "message_bus_propertyid"
580
+ */
581
+ if (!String.prototype.foreign_key)
582
+ {
583
+ String.prototype.foreign_key = function(dropIdUbar)
584
+ {
585
+ var str = this;
586
+ str = str.demodulize().underscore() + ((dropIdUbar) ? ('') : ('_')) + 'id';
587
+ return '' + str;
588
+ };
589
+ }
590
+
591
+ /*
592
+ This function adds ordinalize support to every String object
593
+ Signature:
594
+ String.ordinalize() == String
595
+ Arguments:
596
+ N/A
597
+ Returns:
598
+ String - renders all found numbers their sequence like "22nd"
599
+ Examples:
600
+ "the 1 pitch".ordinalize() == "the 1st pitch"
601
+ */
602
+ if (!String.prototype.ordinalize)
603
+ {
604
+ String.prototype.ordinalize = function()
605
+ {
606
+ var str = this;
607
+ var str_arr = str.split(' ');
608
+ for (var x = 0; x < str_arr.length; x++)
609
+ {
610
+ var i = parseInt(str_arr[x], 10);
611
+ if (!isNaN(i))
612
+ {
613
+ var ltd = str_arr[x].substring(str_arr[x].length - 2);
614
+ var ld = str_arr[x].substring(str_arr[x].length - 1);
615
+ var suf = "th";
616
+ if (ltd != "11" && ltd != "12" && ltd != "13")
617
+ {
618
+ if (ld === "1")
619
+ {
620
+ suf = "st";
621
+ }
622
+ else if (ld === "2")
623
+ {
624
+ suf = "nd";
625
+ }
626
+ else if (ld === "3")
627
+ {
628
+ suf = "rd";
629
+ }
630
+ }
631
+ str_arr[x] += suf;
632
+ }
633
+ }
634
+ str = str_arr.join(' ');
635
+ return '' + str;
636
+ };
637
+ }
@@ -0,0 +1,20 @@
1
+ moduleKeywords = ['extended', 'included']
2
+ @Modules = {}
3
+ class @Module
4
+ @extend: (obj) ->
5
+ obj = obj.prototype || obj
6
+ for key, value of obj when key not in moduleKeywords
7
+ @[key] = value
8
+
9
+ obj.extended?.apply(@)
10
+ this
11
+
12
+ @include: (obj) ->
13
+ obj = obj.prototype || obj
14
+ for key, value of obj when key not in moduleKeywords
15
+ # Assign properties to the prototype
16
+ @::[key] = value
17
+
18
+ obj.included?.apply(@)
19
+ this
20
+ @new: (args...) -> new @(args...)
@@ -0,0 +1,57 @@
1
+ @ActionQuery ?= {}
2
+ class ActionQuery.$PrivateMethods
3
+ __processResponse__: (response) ->
4
+ for key,val of response
5
+ @[key] = val
6
+ @["$#{key}Was"] = val
7
+ format: 'json'
8
+ __destroy__: ->
9
+ route = @__selectRoute__('destroy')
10
+ return @$promise unless route
11
+ return @$promise if @$destroyed
12
+ for key in Object.keys @
13
+ continue unless key.match(/^\$.*Was$/)
14
+ @[key] = null
15
+ @$destroyed = true
16
+ @id = null
17
+ @$promise = $.ajax(
18
+ url: route.path
19
+ method: route.verb
20
+ )
21
+ __save__: ->
22
+ method = if @id then 'update' else 'create'
23
+ route = @__selectRoute__(method)
24
+ data = @__sanitizeParams__()
25
+ # Make sure there is a route
26
+ return @$promise unless route
27
+ # Make sure on update that keys are more than just format
28
+ return @$promise if method == 'update' && Object.keys(data[@constructor.name.underscore()]).length <= 1
29
+
30
+ @$destroyed = false
31
+ @$promise = $.ajax(
32
+ url: route.path
33
+ method: route.verb
34
+ data: data
35
+ )
36
+ .then @__processResponse__.bind(@)
37
+ __selectRoute__: (method) ->
38
+ routes = []
39
+ for route in @__routes__.filter((route) -> route.method == method)
40
+ continue unless route.requirements.subtract(Object.keys(@)).length == 0
41
+ path = route.path
42
+ for key,val of @
43
+ path = path.replace(":#{key}",val)
44
+ path = path.replace /\(.*\)/, (match) ->
45
+ return '' if match.indexOf(':') >= 0
46
+ return match[1..-2]
47
+ routes.push(weight: route.requirements.length, path: path, verb: route.verb)
48
+ weight = routes.pluck('weight').max()
49
+ (routes.filter (route) -> route.weight == weight).first()
50
+ __sanitizeParams__: ->
51
+ data = {}
52
+ data[@constructor.name.underscore()] = {}
53
+ for key,val of @
54
+ continue if key[0] in ['$','_'] || key == 'constructor'
55
+ continue if @[key] == @["$#{key}Was"]
56
+ data[@constructor.name.underscore()][key] = val
57
+ data
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: action_query
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Moody
@@ -74,6 +74,8 @@ extensions: []
74
74
  extra_rdoc_files: []
75
75
  files:
76
76
  - ".gitignore"
77
+ - ".ruby-gemset"
78
+ - ".ruby-version"
77
79
  - CODE_OF_CONDUCT.md
78
80
  - Gemfile
79
81
  - LICENSE.txt
@@ -83,7 +85,15 @@ files:
83
85
  - bin/console
84
86
  - bin/setup
85
87
  - lib/action_query.rb
88
+ - lib/action_query/route.rb
86
89
  - lib/action_query/version.rb
90
+ - lib/assets/javascripts/action_query/base.coffee
91
+ - lib/assets/javascripts/action_query/class_methods.coffee
92
+ - lib/assets/javascripts/action_query/classes.coffee.erb
93
+ - lib/assets/javascripts/action_query/extensions/array.coffee
94
+ - lib/assets/javascripts/action_query/extensions/inflection.js
95
+ - lib/assets/javascripts/action_query/extensions/module.coffee
96
+ - lib/assets/javascripts/action_query/private_methods.coffee
87
97
  homepage: https://github.com/cmoodyEIT/action_query
88
98
  licenses:
89
99
  - MIT