spyro 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.
Files changed (107) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.rdoc +3 -0
  4. data/Rakefile +37 -0
  5. data/app/assets/OLDjavascripts/application.js +25 -0
  6. data/app/assets/OLDjavascripts/components.es6 +10 -0
  7. data/app/assets/OLDjavascripts/components/base/base.es6 +197 -0
  8. data/app/assets/OLDjavascripts/components/base/collection.es6 +199 -0
  9. data/app/assets/OLDjavascripts/components/base/element.es6 +134 -0
  10. data/app/assets/OLDjavascripts/components/base/field.es6 +26 -0
  11. data/app/assets/OLDjavascripts/components/base/inputs/text.es6 +21 -0
  12. data/app/assets/OLDjavascripts/components/base/pagination.es6 +23 -0
  13. data/app/assets/OLDjavascripts/vendor/lodash.js +121 -0
  14. data/app/assets/OLDjavascripts/vendor/moment-twitter.js +86 -0
  15. data/app/assets/OLDjavascripts/vendor/moment.js +80 -0
  16. data/app/assets/OLDjavascripts/vendor/pluralize.js +433 -0
  17. data/app/views/base/_associations.html.haml +11 -0
  18. data/app/views/base/_custom.html.haml +0 -0
  19. data/app/views/base/_details.html.haml +3 -0
  20. data/app/views/base/_edit_header.html.haml +3 -0
  21. data/app/views/base/_fields.html.haml +11 -0
  22. data/app/views/base/_form.html.haml +6 -0
  23. data/app/views/base/_index_header.html.haml +4 -0
  24. data/app/views/base/_new_header.html.haml +3 -0
  25. data/app/views/base/_other_form_fields.html.haml +0 -0
  26. data/app/views/base/_show_header.html.haml +9 -0
  27. data/app/views/base/_upload_fields.html.haml +5 -0
  28. data/app/views/base/copy.html.haml +10 -0
  29. data/app/views/base/edit.html.haml +4 -0
  30. data/app/views/base/index.csv.haml +8 -0
  31. data/app/views/base/index.html.haml +7 -0
  32. data/app/views/base/index.js.haml +2 -0
  33. data/app/views/base/index.xls.ruby +12 -0
  34. data/app/views/base/mailer.html.haml +46 -0
  35. data/app/views/base/new.html.haml +4 -0
  36. data/app/views/base/notify.html.haml +11 -0
  37. data/app/views/base/show.html.haml +8 -0
  38. data/app/views/base/stats.html.haml +36 -0
  39. data/app/views/base/trombi.html.haml +1 -0
  40. data/app/views/base/upload.html.haml +24 -0
  41. data/config/initializers/assets.rb +1 -0
  42. data/config/routes.rb +2 -0
  43. data/lib/spyro.rb +24 -0
  44. data/lib/spyro/active_record_add_on.rb +38 -0
  45. data/lib/spyro/application_controller_add_on.rb +24 -0
  46. data/lib/spyro/collections/outputs/admin_table.rb +28 -0
  47. data/lib/spyro/collections/outputs/bar_graph_table.rb +46 -0
  48. data/lib/spyro/collections/outputs/base.rb +23 -0
  49. data/lib/spyro/collections/outputs/csv.rb +34 -0
  50. data/lib/spyro/collections/outputs/fields.rb +118 -0
  51. data/lib/spyro/collections/outputs/flatui_table.rb +40 -0
  52. data/lib/spyro/collections/outputs/inplace_table.rb +29 -0
  53. data/lib/spyro/collections/outputs/map.rb +22 -0
  54. data/lib/spyro/collections/outputs/table.rb +126 -0
  55. data/lib/spyro/collections/outputs/xlsx.rb +39 -0
  56. data/lib/spyro/collections/parsers/active_ldap_relation.rb +22 -0
  57. data/lib/spyro/collections/parsers/active_record_relation.rb +138 -0
  58. data/lib/spyro/collections/parsers/array.rb +38 -0
  59. data/lib/spyro/collections/parsers/base.rb +60 -0
  60. data/lib/spyro/collections/parsers/kaminari_array.rb +38 -0
  61. data/lib/spyro/collections/parsers/model.rb +31 -0
  62. data/lib/spyro/controllers/strong_parameted.rb +33 -0
  63. data/lib/spyro/engine.rb +6 -0
  64. data/lib/spyro/filters_controller_add_on.rb +161 -0
  65. data/lib/spyro/helpers/action_view_extension.rb +726 -0
  66. data/lib/spyro/namespace_template_inheritance.rb +30 -0
  67. data/lib/spyro/usefull_attributes.rb +14 -0
  68. data/lib/spyro/version.rb +3 -0
  69. data/lib/tasks/spyro_tasks.rake +4 -0
  70. data/test/dummy/README.rdoc +28 -0
  71. data/test/dummy/Rakefile +6 -0
  72. data/test/dummy/app/assets/javascripts/application.js +13 -0
  73. data/test/dummy/app/assets/stylesheets/application.css +15 -0
  74. data/test/dummy/app/controllers/application_controller.rb +5 -0
  75. data/test/dummy/app/helpers/application_helper.rb +2 -0
  76. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  77. data/test/dummy/bin/bundle +3 -0
  78. data/test/dummy/bin/rails +4 -0
  79. data/test/dummy/bin/rake +4 -0
  80. data/test/dummy/bin/setup +29 -0
  81. data/test/dummy/config.ru +4 -0
  82. data/test/dummy/config/application.rb +26 -0
  83. data/test/dummy/config/boot.rb +5 -0
  84. data/test/dummy/config/database.yml +25 -0
  85. data/test/dummy/config/environment.rb +5 -0
  86. data/test/dummy/config/environments/development.rb +41 -0
  87. data/test/dummy/config/environments/production.rb +79 -0
  88. data/test/dummy/config/environments/test.rb +42 -0
  89. data/test/dummy/config/initializers/assets.rb +11 -0
  90. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  91. data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
  92. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  93. data/test/dummy/config/initializers/inflections.rb +16 -0
  94. data/test/dummy/config/initializers/mime_types.rb +4 -0
  95. data/test/dummy/config/initializers/session_store.rb +3 -0
  96. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  97. data/test/dummy/config/locales/en.yml +23 -0
  98. data/test/dummy/config/routes.rb +4 -0
  99. data/test/dummy/config/secrets.yml +22 -0
  100. data/test/dummy/public/404.html +67 -0
  101. data/test/dummy/public/422.html +67 -0
  102. data/test/dummy/public/500.html +66 -0
  103. data/test/dummy/public/favicon.ico +0 -0
  104. data/test/integration/navigation_test.rb +8 -0
  105. data/test/spyro_test.rb +7 -0
  106. data/test/test_helper.rb +21 -0
  107. metadata +256 -0
@@ -0,0 +1,433 @@
1
+ /* global define */
2
+
3
+ (function (root, pluralize) {
4
+ /* istanbul ignore else */
5
+ if (typeof require === 'function' && typeof exports === 'object' && typeof module === 'object') {
6
+ // Node.
7
+ module.exports = pluralize();
8
+ } else if (typeof define === 'function' && define.amd) {
9
+ // AMD, registers as an anonymous module.
10
+ define(function () {
11
+ return pluralize();
12
+ });
13
+ } else {
14
+ // Browser global.
15
+ root.pluralize = pluralize();
16
+ }
17
+ })(this, function () {
18
+ // Rule storage - pluralize and singularize need to be run sequentially,
19
+ // while other rules can be optimized using an object for instant lookups.
20
+ var pluralRules = [];
21
+ var singularRules = [];
22
+ var uncountables = {};
23
+ var irregularPlurals = {};
24
+ var irregularSingles = {};
25
+
26
+ /**
27
+ * Title case a string.
28
+ *
29
+ * @param {string} str
30
+ * @return {string}
31
+ */
32
+ function toTitleCase (str) {
33
+ return str.charAt(0).toUpperCase() + str.substr(1).toLowerCase();
34
+ }
35
+
36
+ /**
37
+ * Sanitize a pluralization rule to a usable regular expression.
38
+ *
39
+ * @param {(RegExp|string)} rule
40
+ * @return {RegExp}
41
+ */
42
+ function sanitizeRule (rule) {
43
+ if (typeof rule === 'string') {
44
+ return new RegExp('^' + rule + '$', 'i');
45
+ }
46
+
47
+ return rule;
48
+ }
49
+
50
+ /**
51
+ * Pass in a word token to produce a function that can replicate the case on
52
+ * another word.
53
+ *
54
+ * @param {string} word
55
+ * @param {string} token
56
+ * @return {Function}
57
+ */
58
+ function restoreCase (word, token) {
59
+ // Upper cased words. E.g. "HELLO".
60
+ if (word === word.toUpperCase()) {
61
+ return token.toUpperCase();
62
+ }
63
+
64
+ // Title cased words. E.g. "Title".
65
+ if (word[0] === word[0].toUpperCase()) {
66
+ return toTitleCase(token);
67
+ }
68
+
69
+ // Lower cased words. E.g. "test".
70
+ return token.toLowerCase();
71
+ }
72
+
73
+ /**
74
+ * Interpolate a regexp string.
75
+ *
76
+ * @param {string} str
77
+ * @param {Array} args
78
+ * @return {string}
79
+ */
80
+ function interpolate (str, args) {
81
+ return str.replace(/\$(\d{1,2})/g, function (match, index) {
82
+ return args[index] || '';
83
+ });
84
+ }
85
+
86
+ /**
87
+ * Sanitize a word by passing in the word and sanitization rules.
88
+ *
89
+ * @param {String} token
90
+ * @param {String} word
91
+ * @param {Array} collection
92
+ * @return {String}
93
+ */
94
+ function sanitizeWord (token, word, collection) {
95
+ // Empty string or doesn't need fixing.
96
+ if (!token.length || uncountables.hasOwnProperty(token)) {
97
+ return word;
98
+ }
99
+
100
+ var len = collection.length;
101
+
102
+ // Iterate over the sanitization rules and use the first one to match.
103
+ while (len--) {
104
+ var rule = collection[len];
105
+
106
+ // If the rule passes, return the replacement.
107
+ if (rule[0].test(word)) {
108
+ return word.replace(rule[0], function (match, index, word) {
109
+ var result = interpolate(rule[1], arguments);
110
+
111
+ if (match === '') {
112
+ return restoreCase(word[index - 1], result);
113
+ }
114
+
115
+ return restoreCase(match, result);
116
+ });
117
+ }
118
+ }
119
+
120
+ return word;
121
+ }
122
+
123
+ /**
124
+ * Replace a word with the updated word.
125
+ *
126
+ * @param {Object} replaceMap
127
+ * @param {Object} keepMap
128
+ * @param {Array} rules
129
+ * @return {Function}
130
+ */
131
+ function replaceWord (replaceMap, keepMap, rules) {
132
+ return function (word) {
133
+ // Get the correct token and case restoration functions.
134
+ var token = word.toLowerCase();
135
+
136
+ // Check against the keep object map.
137
+ if (keepMap.hasOwnProperty(token)) {
138
+ return restoreCase(word, token);
139
+ }
140
+
141
+ // Check against the replacement map for a direct word replacement.
142
+ if (replaceMap.hasOwnProperty(token)) {
143
+ return restoreCase(word, replaceMap[token]);
144
+ }
145
+
146
+ // Run all the rules against the word.
147
+ return sanitizeWord(token, word, rules);
148
+ };
149
+ }
150
+
151
+ /**
152
+ * Pluralize or singularize a word based on the passed in count.
153
+ *
154
+ * @param {String} word
155
+ * @param {Number} count
156
+ * @param {Boolean} inclusive
157
+ * @return {String}
158
+ */
159
+ function pluralize (word, count, inclusive) {
160
+ var pluralized = count === 1
161
+ ? pluralize.singular(word) : pluralize.plural(word);
162
+
163
+ return (inclusive ? count + ' ' : '') + pluralized;
164
+ }
165
+
166
+ /**
167
+ * Pluralize a word.
168
+ *
169
+ * @type {Function}
170
+ */
171
+ pluralize.plural = replaceWord(
172
+ irregularSingles, irregularPlurals, pluralRules
173
+ );
174
+
175
+ /**
176
+ * Singularize a word.
177
+ *
178
+ * @type {Function}
179
+ */
180
+ pluralize.singular = replaceWord(
181
+ irregularPlurals, irregularSingles, singularRules
182
+ );
183
+
184
+ /**
185
+ * Add a pluralization rule to the collection.
186
+ *
187
+ * @param {(string|RegExp)} rule
188
+ * @param {string} replacement
189
+ */
190
+ pluralize.addPluralRule = function (rule, replacement) {
191
+ pluralRules.push([sanitizeRule(rule), replacement]);
192
+ };
193
+
194
+ /**
195
+ * Add a singularization rule to the collection.
196
+ *
197
+ * @param {(string|RegExp)} rule
198
+ * @param {string} replacement
199
+ */
200
+ pluralize.addSingularRule = function (rule, replacement) {
201
+ singularRules.push([sanitizeRule(rule), replacement]);
202
+ };
203
+
204
+ /**
205
+ * Add an uncountable word rule.
206
+ *
207
+ * @param {(string|RegExp)} word
208
+ */
209
+ pluralize.addUncountableRule = function (word) {
210
+ if (typeof word === 'string') {
211
+ uncountables[word.toLowerCase()] = true;
212
+ return;
213
+ }
214
+
215
+ // Set singular and plural references for the word.
216
+ pluralize.addPluralRule(word, '$0');
217
+ pluralize.addSingularRule(word, '$0');
218
+ };
219
+
220
+ /**
221
+ * Add an irregular word definition.
222
+ *
223
+ * @param {String} single
224
+ * @param {String} plural
225
+ */
226
+ pluralize.addIrregularRule = function (single, plural) {
227
+ plural = plural.toLowerCase();
228
+ single = single.toLowerCase();
229
+
230
+ irregularSingles[single] = plural;
231
+ irregularPlurals[plural] = single;
232
+ };
233
+
234
+ /**
235
+ * Irregular rules.
236
+ */
237
+ [
238
+ // Pronouns.
239
+ ['I', 'we'],
240
+ ['me', 'us'],
241
+ ['he', 'they'],
242
+ ['she', 'they'],
243
+ ['them', 'them'],
244
+ ['myself', 'ourselves'],
245
+ ['yourself', 'yourselves'],
246
+ ['itself', 'themselves'],
247
+ ['herself', 'themselves'],
248
+ ['himself', 'themselves'],
249
+ ['themself', 'themselves'],
250
+ ['is', 'are'],
251
+ ['this', 'these'],
252
+ ['that', 'those'],
253
+ // Words ending in with a consonant and `o`.
254
+ ['echo', 'echoes'],
255
+ ['dingo', 'dingoes'],
256
+ ['volcano', 'volcanoes'],
257
+ ['tornado', 'tornadoes'],
258
+ ['torpedo', 'torpedoes'],
259
+ // Ends with `us`.
260
+ ['genus', 'genera'],
261
+ ['viscus', 'viscera'],
262
+ // Ends with `ma`.
263
+ ['stigma', 'stigmata'],
264
+ ['stoma', 'stomata'],
265
+ ['dogma', 'dogmata'],
266
+ ['lemma', 'lemmata'],
267
+ ['schema', 'schemata'],
268
+ ['anathema', 'anathemata'],
269
+ // Other irregular rules.
270
+ ['ox', 'oxen'],
271
+ ['axe', 'axes'],
272
+ ['die', 'dice'],
273
+ ['yes', 'yeses'],
274
+ ['foot', 'feet'],
275
+ ['eave', 'eaves'],
276
+ ['goose', 'geese'],
277
+ ['tooth', 'teeth'],
278
+ ['quiz', 'quizzes'],
279
+ ['human', 'humans'],
280
+ ['proof', 'proofs'],
281
+ ['carve', 'carves'],
282
+ ['valve', 'valves'],
283
+ ['thief', 'thieves'],
284
+ ['genie', 'genies'],
285
+ ['groove', 'grooves'],
286
+ ['pickaxe', 'pickaxes'],
287
+ ['whiskey', 'whiskies']
288
+ ].forEach(function (rule) {
289
+ return pluralize.addIrregularRule(rule[0], rule[1]);
290
+ });
291
+
292
+ /**
293
+ * Pluralization rules.
294
+ */
295
+ [
296
+ [/s?$/i, 's'],
297
+ [/([^aeiou]ese)$/i, '$1'],
298
+ [/(ax|test)is$/i, '$1es'],
299
+ [/(alias|[^aou]us|tlas|gas|ris)$/i, '$1es'],
300
+ [/(e[mn]u)s?$/i, '$1s'],
301
+ [/([^l]ias|[aeiou]las|[emjzr]as|[iu]am)$/i, '$1'],
302
+ [/(alumn|syllab|octop|vir|radi|nucle|fung|cact|stimul|termin|bacill|foc|uter|loc|strat)(?:us|i)$/i, '$1i'],
303
+ [/(alumn|alg|vertebr)(?:a|ae)$/i, '$1ae'],
304
+ [/(seraph|cherub)(?:im)?$/i, '$1im'],
305
+ [/(her|at|gr)o$/i, '$1oes'],
306
+ [/(agend|addend|millenni|dat|extrem|bacteri|desiderat|strat|candelabr|errat|ov|symposi|curricul|automat|quor)(?:a|um)$/i, '$1a'],
307
+ [/(apheli|hyperbat|periheli|asyndet|noumen|phenomen|criteri|organ|prolegomen|hedr|automat)(?:a|on)$/i, '$1a'],
308
+ [/sis$/i, 'ses'],
309
+ [/(?:(kni|wi|li)fe|(ar|l|ea|eo|oa|hoo)f)$/i, '$1$2ves'],
310
+ [/([^aeiouy]|qu)y$/i, '$1ies'],
311
+ [/([^ch][ieo][ln])ey$/i, '$1ies'],
312
+ [/(x|ch|ss|sh|zz)$/i, '$1es'],
313
+ [/(matr|cod|mur|sil|vert|ind|append)(?:ix|ex)$/i, '$1ices'],
314
+ [/(m|l)(?:ice|ouse)$/i, '$1ice'],
315
+ [/(pe)(?:rson|ople)$/i, '$1ople'],
316
+ [/(child)(?:ren)?$/i, '$1ren'],
317
+ [/eaux$/i, '$0'],
318
+ [/m[ae]n$/i, 'men'],
319
+ ['thou', 'you']
320
+ ].forEach(function (rule) {
321
+ return pluralize.addPluralRule(rule[0], rule[1]);
322
+ });
323
+
324
+ /**
325
+ * Singularization rules.
326
+ */
327
+ [
328
+ [/s$/i, ''],
329
+ [/(ss)$/i, '$1'],
330
+ [/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)(?:sis|ses)$/i, '$1sis'],
331
+ [/(^analy)(?:sis|ses)$/i, '$1sis'],
332
+ [/(wi|kni|(?:after|half|high|low|mid|non|night|[^\w]|^)li)ves$/i, '$1fe'],
333
+ [/(ar|(?:wo|[ae])l|[eo][ao])ves$/i, '$1f'],
334
+ [/([^aeiouy]|qu)ies$/i, '$1y'],
335
+ [/(^[pl]|zomb|^(?:neck)?t|[aeo][lt]|cut)ies$/i, '$1ie'],
336
+ [/(\b(?:mon|smil))ies$/i, '$1ey'],
337
+ [/(m|l)ice$/i, '$1ouse'],
338
+ [/(seraph|cherub)im$/i, '$1'],
339
+ [/(x|ch|ss|sh|zz|tto|go|cho|alias|[^aou]us|tlas|gas|(?:her|at|gr)o|ris)(?:es)?$/i, '$1'],
340
+ [/(e[mn]u)s?$/i, '$1'],
341
+ [/(movie|twelve)s$/i, '$1'],
342
+ [/(cris|test|diagnos)(?:is|es)$/i, '$1is'],
343
+ [/(alumn|syllab|octop|vir|radi|nucle|fung|cact|stimul|termin|bacill|foc|uter|loc|strat)(?:us|i)$/i, '$1us'],
344
+ [/(agend|addend|millenni|dat|extrem|bacteri|desiderat|strat|candelabr|errat|ov|symposi|curricul|quor)a$/i, '$1um'],
345
+ [/(apheli|hyperbat|periheli|asyndet|noumen|phenomen|criteri|organ|prolegomen|hedr|automat)a$/i, '$1on'],
346
+ [/(alumn|alg|vertebr)ae$/i, '$1a'],
347
+ [/(cod|mur|sil|vert|ind)ices$/i, '$1ex'],
348
+ [/(matr|append)ices$/i, '$1ix'],
349
+ [/(pe)(rson|ople)$/i, '$1rson'],
350
+ [/(child)ren$/i, '$1'],
351
+ [/(eau)x?$/i, '$1'],
352
+ [/men$/i, 'man']
353
+ ].forEach(function (rule) {
354
+ return pluralize.addSingularRule(rule[0], rule[1]);
355
+ });
356
+
357
+ /**
358
+ * Uncountable rules.
359
+ */
360
+ [
361
+ // Singular words with no plurals.
362
+ 'advice',
363
+ 'agenda',
364
+ 'bison',
365
+ 'bream',
366
+ 'buffalo',
367
+ 'carp',
368
+ 'chassis',
369
+ 'cod',
370
+ 'cooperation',
371
+ 'corps',
372
+ 'digestion',
373
+ 'debris',
374
+ 'diabetes',
375
+ 'energy',
376
+ 'equipment',
377
+ 'elk',
378
+ 'excretion',
379
+ 'expertise',
380
+ 'flounder',
381
+ 'gallows',
382
+ 'garbage',
383
+ 'graffiti',
384
+ 'headquarters',
385
+ 'health',
386
+ 'herpes',
387
+ 'highjinks',
388
+ 'homework',
389
+ 'information',
390
+ 'jeans',
391
+ 'justice',
392
+ 'kudos',
393
+ 'labour',
394
+ 'machinery',
395
+ 'mackerel',
396
+ 'media',
397
+ 'mews',
398
+ 'moose',
399
+ 'news',
400
+ 'pike',
401
+ 'plankton',
402
+ 'pliers',
403
+ 'pollution',
404
+ 'premises',
405
+ 'rain',
406
+ 'rice',
407
+ 'salmon',
408
+ 'scissors',
409
+ 'series',
410
+ 'sewage',
411
+ 'shambles',
412
+ 'shrimp',
413
+ 'species',
414
+ 'staff',
415
+ 'swine',
416
+ 'trout',
417
+ 'tuna',
418
+ 'whiting',
419
+ 'wildebeest',
420
+ 'wildlife',
421
+ 'you',
422
+ // Regexes.
423
+ /pox$/i, // "chickpox", "smallpox"
424
+ /ois$/i,
425
+ /deer$/i, // "deer", "reindeer"
426
+ /fish$/i, // "fish", "blowfish", "angelfish"
427
+ /sheep$/i,
428
+ /measles$/i,
429
+ /[^aeiou]ese$/i // "chinese", "japanese"
430
+ ].forEach(pluralize.addUncountableRule);
431
+
432
+ return pluralize;
433
+ });
@@ -0,0 +1,11 @@
1
+ - resource_class.reflections.select {|s, r| s and r.macro == :has_many}.each do |symbol, reflection|
2
+ = box do
3
+ = header symbol.to_s.humanize do
4
+ = button "#{t('scaffold.btn.create', :default => 'Create')}", new_polymorphic_path([*parents, resource, symbol.to_s.singularize]) if can? :new, symbol.to_s.singularize.classify.constantize rescue nil
5
+ = button "#{t('scaffold.btn.index', :default => 'Index')}", polymorphic_path([*parents, resource, symbol]) if can? :index, symbol.to_s.singularize.classify.constantize rescue nil
6
+ - controller = "#{symbol.to_s.classify.pluralize}Controller".constantize rescue nil
7
+ = download_mime_type_btns(controller) {|format| polymorphic_path([*parents, resource, symbol], format: format)} if controller and can? :index, symbol.to_s.singularize.classify.constantize #rescue nil
8
+ - array = resource.send(symbol).page(params["page_#{symbol}".to_sym])
9
+ = paginate array, :param_name => "page_#{symbol}".to_sym
10
+ = collection_for array, :parents => [*parents, resource]
11
+ = paginate array, :param_name => "page_#{symbol}".to_sym
File without changes
@@ -0,0 +1,3 @@
1
+ = box do
2
+ = header resource_class.to_s.humanize
3
+ = collection_for resource, :parents => parents