k_domain 0.0.14 → 0.0.23

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/.builders/config/_.rb +3 -0
  3. data/.builders/setup.rb +30 -0
  4. data/.gitignore +1 -0
  5. data/.rubocop.yml +4 -3
  6. data/Gemfile +1 -1
  7. data/Guardfile +1 -0
  8. data/README.md +15 -0
  9. data/STORIES.md +35 -6
  10. data/k_domain.gemspec +1 -1
  11. data/lib/k_domain/domain_model/load.rb +8 -2
  12. data/lib/k_domain/domain_model/transform.rb +34 -51
  13. data/lib/k_domain/domain_model/transform_steps/_.rb +8 -6
  14. data/lib/k_domain/domain_model/transform_steps/step.rb +47 -2
  15. data/lib/k_domain/domain_model/transform_steps/{step1_attach_db_schema.rb → step1_db_schema.rb} +2 -1
  16. data/lib/k_domain/domain_model/transform_steps/{step5_attach_dictionary.rb → step20_dictionary.rb} +7 -3
  17. data/lib/k_domain/domain_model/transform_steps/step2_domain_models.rb +123 -0
  18. data/lib/k_domain/domain_model/transform_steps/{step8_locate_rails_models.rb → step4_rails_resource_models.rb} +4 -4
  19. data/lib/k_domain/domain_model/transform_steps/step5_rails_resource_routes.rb +36 -0
  20. data/lib/k_domain/domain_model/transform_steps/step6_rails_structure_models.rb +90 -0
  21. data/lib/k_domain/domain_model/transform_steps/step7_rails_structure_controllers.rb +109 -0
  22. data/lib/k_domain/domain_model/transform_steps/{step3_attach_columns.rb → step8_domain_columns.rb} +40 -73
  23. data/lib/k_domain/rails_code_extractor/_.rb +5 -0
  24. data/lib/k_domain/rails_code_extractor/extract_controller.rb +59 -0
  25. data/lib/k_domain/rails_code_extractor/extract_model.rb +69 -0
  26. data/lib/k_domain/rails_code_extractor/shim_loader.rb +30 -0
  27. data/lib/k_domain/raw_db_schema/load.rb +8 -2
  28. data/lib/k_domain/raw_db_schema/transform.rb +9 -8
  29. data/lib/k_domain/schemas/_.rb +3 -2
  30. data/lib/k_domain/schemas/database.rb +86 -0
  31. data/lib/k_domain/schemas/domain/erd_file.rb +2 -0
  32. data/lib/k_domain/schemas/domain.rb +154 -0
  33. data/lib/k_domain/schemas/domain_model.rb +6 -5
  34. data/lib/k_domain/schemas/rails_resource.rb +43 -6
  35. data/lib/k_domain/schemas/rails_structure.rb +172 -0
  36. data/lib/k_domain/version.rb +1 -1
  37. data/lib/k_domain.rb +2 -0
  38. data/templates/custom/action_controller.rb +36 -0
  39. data/templates/custom/controller_interceptors.rb +78 -0
  40. data/templates/custom/model_interceptors.rb +71 -0
  41. data/templates/load_schema.rb +7 -0
  42. data/templates/old_printspeek_schema copy.rb +231 -0
  43. data/templates/old_printspeek_schema.rb +233 -0
  44. data/templates/rails/action_controller.rb +301 -0
  45. data/templates/rails/active_record.rb +348 -0
  46. data/templates/ruby_code_extractor/attach_class_info.rb +13 -0
  47. data/templates/ruby_code_extractor/behaviour_accessors.rb +39 -0
  48. data/templates/simple/controller_interceptors.rb +2 -0
  49. metadata +30 -17
  50. data/lib/k_domain/domain_model/transform_steps/step2_attach_models.rb +0 -62
  51. data/lib/k_domain/domain_model/transform_steps/step4_attach_erd_files.rb +0 -454
  52. data/lib/k_domain/schemas/database/_.rb +0 -7
  53. data/lib/k_domain/schemas/database/foreign_key.rb +0 -14
  54. data/lib/k_domain/schemas/database/index.rb +0 -14
  55. data/lib/k_domain/schemas/database/schema.rb +0 -31
  56. data/lib/k_domain/schemas/database/table.rb +0 -32
  57. data/lib/k_domain/schemas/domain/domain.rb +0 -11
  58. data/lib/k_domain/schemas/domain/models/column.rb +0 -49
  59. data/lib/k_domain/schemas/domain/models/model.rb +0 -111
@@ -0,0 +1,301 @@
1
+ # Implement data capture methods for the Rails Action Controller class
2
+ #
3
+ # This Shim will intercept any DSL methods and convert their paramaters into a data hash
4
+ module ActionController
5
+ extend RubyCodeExtractor::AttachClassInfo
6
+
7
+ class Base
8
+ extend RubyCodeExtractor::BehaviourAccessors
9
+
10
+ def self.singleton_class
11
+ Class.new do
12
+ def send(*_p, **_o); end
13
+ end.new
14
+ end
15
+
16
+ def self.class_info
17
+ return ActionController.class_info if ActionController.class_info
18
+
19
+ ActionController.class_info = {
20
+ class_name: name
21
+ }
22
+ end
23
+
24
+ def self.after_action(name, **opts)
25
+ add(:after_action, {
26
+ name: name,
27
+ opts: opts
28
+ })
29
+ end
30
+
31
+ def self.around_action(name, **opts)
32
+ add(:around_action, {
33
+ name: name,
34
+ opts: opts
35
+ })
36
+ end
37
+
38
+ def self.before_action(name, **opts)
39
+ add(:before_action, {
40
+ name: name,
41
+ opts: opts
42
+ })
43
+ end
44
+
45
+ def self.prepend_before_action(name, **opts)
46
+ add(:prepend_before_action, {
47
+ name: name,
48
+ opts: opts
49
+ })
50
+ end
51
+
52
+ def self.skip_before_action(name, **opts)
53
+ add(:skip_before_action, {
54
+ name: name,
55
+ opts: opts
56
+ })
57
+ end
58
+
59
+ def self.before_filter(name, **opts)
60
+ add(:before_filter, {
61
+ name: name,
62
+ opts: opts
63
+ })
64
+ end
65
+
66
+ def self.skip_before_filter(name, **opts)
67
+ add(:skip_before_filter, {
68
+ name: name,
69
+ opts: opts
70
+ })
71
+ end
72
+
73
+ def self.layout(name, **opts)
74
+ set(:layout, {
75
+ name: name,
76
+ opts: opts
77
+ })
78
+ end
79
+
80
+ def self.rescue_from(type)#, &block)
81
+ # block_source = nil
82
+ # block_source = lambda_source(block, 'default_scope') if block_given?
83
+
84
+ add(:rescue_from, {
85
+ type: type#,
86
+ # block: block_source
87
+ })
88
+ end
89
+
90
+ # TODO: https://apidock.com/rails/ActionController/Helpers/ClassMethods/helper_method (MAYBE DEPRECATED?)
91
+ def self.helper_method(*names)
92
+ add(:helper_method, {
93
+ names: names
94
+ })
95
+ end
96
+
97
+ # TODO: https://apidock.com/rails/ActionController/Helpers/ClassMethods/helper
98
+ def self.helper(name)
99
+ add(:helper, {
100
+ name: name
101
+ })
102
+ end
103
+
104
+ def self.http_basic_authenticate_with(**opts)
105
+ set(:http_basic_authenticate_with, {
106
+ opts: opts
107
+ })
108
+ end
109
+
110
+ def self.protect_from_forgery(**opts)
111
+ set(:protect_from_forgery, {
112
+ opts: opts
113
+ })
114
+ end
115
+ end
116
+ end
117
+
118
+ # after_action
119
+ # after_filter
120
+ # append_after_action
121
+ # append_after_filter
122
+ # append_around_action
123
+ # append_around_filter
124
+ # append_before_action
125
+ # append_before_filter
126
+ # append_view_path
127
+ # around_action
128
+ # around_filter
129
+ # before_action
130
+ # before_filter
131
+ # controller_name
132
+ # controller_path
133
+ # helper
134
+ # helper_attr
135
+ # helper_method
136
+ # helpers
137
+ # helpers_path
138
+ # hide_action
139
+ # http_basic_authenticate_with
140
+ # layout
141
+ # prepend_after_action
142
+ # prepend_after_filter
143
+ # prepend_around_action
144
+ # prepend_around_filter
145
+ # prepend_before_action
146
+ # prepend_before_filter
147
+ # prepend_view_path
148
+ # protect_from_forgery
149
+ # protected_instance_variables
150
+ # rescue_from
151
+ # reset_callbacks
152
+ # skip_action_callback
153
+ # skip_after_action
154
+ # skip_after_filter
155
+ # skip_around_action
156
+ # skip_around_filter
157
+ # skip_before_action
158
+ # skip_before_filter
159
+ # skip_callback
160
+ # skip_filter
161
+
162
+ # METHOD LIST - Just from running self.class.methods - Object.methods on a running controller
163
+ # action
164
+ # action_methods
165
+ # add_flash_types
166
+ # after_action
167
+ # after_filter
168
+ # all_helpers_from_path
169
+ # allow_forgery_protection
170
+ # allow_forgery_protection=
171
+ # append_after_action
172
+ # append_after_filter
173
+ # append_around_action
174
+ # append_around_filter
175
+ # append_before_action
176
+ # append_before_filter
177
+ # append_view_path
178
+ # around_action
179
+ # around_filter
180
+ # asset_host
181
+ # asset_host=
182
+ # assets_dir
183
+ # assets_dir=
184
+ # before_action
185
+ # before_filter
186
+ # cache_store
187
+ # cache_store=
188
+ # call
189
+ # clear_action_methods!
190
+ # clear_helpers
191
+ # clear_respond_to
192
+ # config
193
+ # config_accessor
194
+ # configure
195
+ # controller_name
196
+ # controller_path
197
+ # default_asset_host_protocol
198
+ # default_asset_host_protocol=
199
+ # default_static_extension
200
+ # default_static_extension=
201
+ # default_url_options
202
+ # default_url_options=
203
+ # default_url_options?
204
+ # define_callbacks
205
+ # devise_group
206
+ # direct_descendants
207
+ # etag
208
+ # etag_with_template_digest
209
+ # etag_with_template_digest=
210
+ # etag_with_template_digest?
211
+ # etaggers
212
+ # etaggers=
213
+ # etaggers?
214
+ # force_ssl
215
+ # forgery_protection_strategy
216
+ # forgery_protection_strategy=
217
+ # get_callbacks
218
+ # helper
219
+ # helper_attr
220
+ # helper_method
221
+ # helpers
222
+ # helpers_path
223
+ # helpers_path=
224
+ # helpers_path?
225
+ # hidden_actions
226
+ # hidden_actions=
227
+ # hidden_actions?
228
+ # hide_action
229
+ # http_basic_authenticate_with
230
+ # include_all_helpers
231
+ # include_all_helpers=
232
+ # include_all_helpers?
233
+ # inherited
234
+ # internal_methods
235
+ # javascripts_dir
236
+ # javascripts_dir=
237
+ # layout
238
+ # log_process_action
239
+ # log_warning_on_csrf_failure
240
+ # log_warning_on_csrf_failure=
241
+ # logger
242
+ # logger=
243
+ # method_added
244
+ # middleware
245
+ # middleware_stack
246
+ # middleware_stack=
247
+ # middleware_stack?
248
+ # mimes_for_respond_to
249
+ # mimes_for_respond_to=
250
+ # mimes_for_respond_to?
251
+ # modules_for_helpers
252
+ # normalize_callback_params
253
+ # perform_caching
254
+ # perform_caching=
255
+ # prepend_after_action
256
+ # prepend_after_filter
257
+ # prepend_around_action
258
+ # prepend_around_filter
259
+ # prepend_before_action
260
+ # prepend_before_filter
261
+ # prepend_view_path
262
+ # protect_from_forgery
263
+ # protected_instance_variables
264
+ # relative_url_root
265
+ # relative_url_root=
266
+ # request_forgery_protection_token
267
+ # request_forgery_protection_token=
268
+ # rescue_from
269
+ # rescue_handlers
270
+ # rescue_handlers=
271
+ # rescue_handlers?
272
+ # reset_callbacks
273
+ # respond_to
274
+ # responder
275
+ # responder=
276
+ # responder?
277
+ # responders
278
+ # set_callback
279
+ # set_callbacks
280
+ # skip_action_callback
281
+ # skip_after_action
282
+ # skip_after_filter
283
+ # skip_around_action
284
+ # skip_around_filter
285
+ # skip_before_action
286
+ # skip_before_filter
287
+ # skip_callback
288
+ # skip_filter
289
+ # stylesheets_dir
290
+ # stylesheets_dir=
291
+ # supports_path?
292
+ # use
293
+ # use_renderer
294
+ # use_renderers
295
+ # view_cache_dependency
296
+ # view_context_class
297
+ # view_paths
298
+ # view_paths=
299
+ # visible_action?
300
+ # without_modules
301
+ # wrap_parameters
@@ -0,0 +1,348 @@
1
+ module ActiveRecord
2
+ extend RubyCodeExtractor::AttachClassInfo
3
+
4
+ class Base
5
+ extend RubyCodeExtractor::BehaviourAccessors
6
+
7
+ def self.singleton_class
8
+ Class.new do
9
+ def send(*_p, **_o); end
10
+ end.new
11
+ end
12
+
13
+ def self.class_info
14
+ return ActiveRecord.class_info if ActiveRecord.class_info
15
+
16
+ ActiveRecord.class_info = {
17
+ class_name: name
18
+ }
19
+ end
20
+
21
+ # -------------------------
22
+ # Intercept methods
23
+ # -------------------------
24
+
25
+ def self.clear_active_connections!; end
26
+
27
+ # -------------------------
28
+ # Behaviour storage methods
29
+ # -------------------------
30
+
31
+ # examples:
32
+ # enum status: { active: 0, archived: 1 }
33
+ # enum status: [:active, :archived]
34
+ # enum status: [:active, :archived], _suffix: true
35
+ # enum comments_status: [:active, :inactive], _prefix: :comments
36
+ def self.enum(**opts)
37
+ add(:enum, opts)
38
+ end
39
+
40
+ # def self.attr_accessor(*args)
41
+ # args.each do |arg|
42
+ # self.class_eval("def #{arg};@#{arg};end")
43
+ # self.class_eval("def #{arg}=(val);@#{arg}=val;end")
44
+ # end
45
+ # end
46
+ # def self.attr_reader(*args)
47
+ # args.each do |arg|
48
+ # self.class_eval("def #{arg};@#{arg};end")
49
+ # end
50
+ # end
51
+ # def self.attr_writer(*args)
52
+ # args.each do |arg|
53
+ # self.class_eval("def #{arg};@#{arg};end")
54
+ # self.class_eval("def #{arg}=(val);@#{arg}=val;end")
55
+ # end
56
+ # end
57
+
58
+ def self.attr_accessor(*names)
59
+ super(*names)
60
+ add(:attr_accessor, names)
61
+ end
62
+
63
+ def self.attr_reader(*names)
64
+ super(*names)
65
+ add(:attr_reader, names)
66
+ end
67
+
68
+ def self.attr_writer(*names)
69
+ super(*names)
70
+ add(:attr_writer, names)
71
+ end
72
+
73
+ def self.lambda_source(a_lambda, prefix = nil)
74
+ return nil unless a_lambda
75
+
76
+ puts 'NOT A LAMBDA' unless a_lambda.is_a?(Proc)
77
+
78
+ result = a_lambda&.source&.strip
79
+ result = result&.delete_prefix(prefix) if prefix
80
+ result&.strip
81
+ end
82
+
83
+ # examples
84
+ # default_scope where(:published => true) # NOT supported
85
+ # default_scope { where(:published_at => Time.now - 1.week) }
86
+ # default_scope -> { order(:external_updated_at) }
87
+ # default_scope -> { where(:published => true) }, all_queries: true
88
+ def self.default_scope(**opts, &block)
89
+ block_source = nil
90
+ block_source = lambda_source(block, 'default_scope') if block_given?
91
+
92
+ set(:default_scope, opts.merge(block: block_source))
93
+ end
94
+
95
+ # examples
96
+ # scope :red, where(:color => 'red') # NOT SUPPORTED
97
+ # scope :dry_clean_only, joins(:washing_instructions).where('washing_instructions.dry_clean_only = ?', true) # NOT SUPPORTED
98
+ #
99
+ def self.scope(name, on_the_lamb = nil, **opts)
100
+ lamb_source = lambda_source(on_the_lamb, "scope :#{name},")
101
+
102
+ add(:scopes, {
103
+ name: name,
104
+ opts: opts,
105
+ block: lamb_source
106
+ })
107
+ end
108
+
109
+ def self.belongs_to(name, on_the_lamb = nil, **opts)
110
+ lamb_source = lambda_source(on_the_lamb, "belongs_to :#{name},")
111
+
112
+ value = {
113
+ name: name,
114
+ opts: opts,
115
+ block: lamb_source
116
+ }
117
+
118
+ value[:opts][:foreign_key] = "#{name}_id" unless value[:opts][:foreign_key]
119
+
120
+ add(:belongs_to, value)
121
+ end
122
+
123
+ def self.has_many(name, on_the_lamb = nil, **opts)
124
+ lamb_source = lambda_source(on_the_lamb, "has_many :#{name},")
125
+
126
+ add(:has_many, {
127
+ name: name,
128
+ opts: opts,
129
+ block: lamb_source
130
+ })
131
+ end
132
+
133
+ def self.has_one(name, on_the_lamb = nil, **opts)
134
+ lamb_source = lambda_source(on_the_lamb, "has_one :#{name},")
135
+
136
+ add(:has_one, {
137
+ name: name,
138
+ opts: opts,
139
+ block: lamb_source
140
+ })
141
+ end
142
+
143
+ def self.has_and_belongs_to_many(name, on_the_lamb = nil, **opts)
144
+ lamb_source = lambda_source(on_the_lamb, "has_and_belongs_to_many :#{name},")
145
+
146
+ add(:has_and_belongs_to_many, {
147
+ name: name,
148
+ opts: opts,
149
+ block: lamb_source
150
+ })
151
+ end
152
+
153
+ def self.validate(*names, **opts, &block)
154
+ block_source = nil
155
+ block_source = lambda_source(block, 'validate') if block_given?
156
+
157
+ add(:validate, {
158
+ names: names,
159
+ opts: opts,
160
+ block: block_source
161
+ })
162
+ end
163
+
164
+ def self.validates(name, **opts)
165
+ add(:validates, {
166
+ name: name,
167
+ opts: opts
168
+ })
169
+ end
170
+
171
+ def self.alias_attribute(left, right)
172
+ add(:alias_attribute, {
173
+ left: left,
174
+ right: right
175
+ })
176
+ end
177
+
178
+ def self.before_create(name)
179
+ add(:before_create, {
180
+ name: name
181
+ })
182
+ end
183
+
184
+ def self.before_save(name)
185
+ add(:before_save, {
186
+ name: name
187
+ })
188
+ end
189
+
190
+ def self.before_destroy(name)
191
+ add(:before_destroy, {
192
+ name: name
193
+ })
194
+ end
195
+
196
+ def self.before_validation(name = nil, &block)
197
+ block_source = nil
198
+ block_source = lambda_source(block, 'before_validation') if block_given?
199
+
200
+ add(:before_validation, {
201
+ name: name,
202
+ block: block_source
203
+ })
204
+ end
205
+
206
+ def self.after_create(name)
207
+ add(:after_create, {
208
+ name: name
209
+ })
210
+ end
211
+
212
+ def self.after_save(name)
213
+ add(:after_save, {
214
+ name: name
215
+ })
216
+ end
217
+
218
+ def self.after_destroy(name = nil, &block)
219
+ block_source = nil
220
+ block_source = lambda_source(block, 'after_destroy') if block_given?
221
+
222
+ add(:after_destroy, {
223
+ name: name,
224
+ block: block_source
225
+ })
226
+ end
227
+
228
+ def self.after_commit(name)
229
+ add(:after_commit, {
230
+ name: name
231
+ })
232
+ end
233
+
234
+ def self.accepts_nested_attributes_for(name, **opts)
235
+ add(:accepts_nested_attributes_for, {
236
+ name: name,
237
+ opts: opts
238
+ })
239
+ end
240
+
241
+ def self.has_secure_token(name)
242
+ add(:has_secure_token, {
243
+ name: name
244
+ })
245
+ end
246
+
247
+ # CAN THESE BE AUTOMATED LIKE INCLUDE MODULES
248
+ def self.establish_connection(connection)
249
+ class_info[:establish_connection] = connection
250
+ end
251
+
252
+ def self.store_accessor(*names)
253
+ class_info[:store_accessor] = *names
254
+ end
255
+
256
+ def self.table_name=(table_name)
257
+ class_info[:table_name] = table_name
258
+ end
259
+
260
+ def self.primary_key=(primary_key)
261
+ class_info[:primary_key] = primary_key
262
+ end
263
+
264
+ def self.require(require)
265
+ add(:require, require)
266
+ end
267
+
268
+ def self.devise(*names)
269
+ add(:devise, names)
270
+ end
271
+
272
+ def self.pg_search_scope(name, **opts)
273
+ custom_set(:pg_search_scope, {
274
+ name: name,
275
+ opts: opts
276
+ })
277
+ end
278
+
279
+ def self.acts_as_readable(**opts)
280
+ custom_set(:acts_as_readable, {
281
+ opts: opts
282
+ })
283
+ end
284
+
285
+ def self.acts_as_reader
286
+ custom_set(:acts_as_reader, {})
287
+ end
288
+
289
+ def self.acts_as_commentable
290
+ custom_set(:acts_as_commentable, {})
291
+ end
292
+
293
+ def self.acts_as_list(**opts)
294
+ custom_set(:acts_as_list, {
295
+ opts: opts
296
+ })
297
+ end
298
+
299
+ def self.has_paper_trail
300
+ custom_set(:has_paper_trail)
301
+ end
302
+
303
+ def self.validates_uniqueness_of(name, **opts)
304
+ custom_set(:validates_uniqueness_of, {
305
+ name: name,
306
+ opts: opts
307
+ })
308
+ end
309
+
310
+ def self.validates_presence_of(name, **opts)
311
+ custom_set(:validates_presence_of, {
312
+ name: name,
313
+ opts: opts
314
+ })
315
+ end
316
+
317
+ def self.validates_length_of(name, **opts)
318
+ custom_set(:validates_length_of, {
319
+ name: name,
320
+ opts: opts
321
+ })
322
+ end
323
+
324
+ def self.attr_encrypted(name, **opts)
325
+ custom_set(:attr_encrypted, {
326
+ name: name,
327
+ opts: opts
328
+ })
329
+ end
330
+
331
+ def self.validates_confirmation_of(name, **opts)
332
+ custom_set(:validates_confirmation_of, {
333
+ name: name,
334
+ opts: opts
335
+ })
336
+ end
337
+
338
+ def self.with_options(opts, &block)
339
+ block_source = nil
340
+ block_source = lambda_source(block) if block_given?
341
+
342
+ custom_add(:with_options, {
343
+ opts: opts,
344
+ block: block_source
345
+ })
346
+ end
347
+ end
348
+ end
@@ -0,0 +1,13 @@
1
+ module RubyCodeExtractor
2
+ # Class Info hash that contains the class name and any other key/values
3
+ # that could be useful when capturing Class information.
4
+ module AttachClassInfo
5
+ def class_info
6
+ @class_info ||= nil
7
+ end
8
+
9
+ def class_info=(value)
10
+ @class_info = value
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,39 @@
1
+ module RubyCodeExtractor
2
+ # When you intercept a method call, you can persist the captured paramaters
3
+ # into a Hash, the Hash Key should be the method name and the value should
4
+ # be a Hash with captured values.
5
+ #
6
+ # Use set/add for standard Rails DSL methods
7
+ # Use custom_set/custom_add for non standard or 3rd party GEM methods
8
+ module BehaviourAccessors
9
+ def set(key, value)
10
+ class_info[key] = class_info[key] || {}
11
+ class_info[key] = value
12
+ end
13
+
14
+ def add(key, value)
15
+ class_info[key] = class_info[key] || []
16
+ if value.is_a?(Array)
17
+ class_info[key] = class_info[key] + value
18
+ else
19
+ class_info[key] << value
20
+ end
21
+ end
22
+
23
+ def custom_set(key, value = {})
24
+ class_info[:custom] = {} unless class_info[:custom]
25
+ class_info[:custom][key] = class_info[:custom][key] || {}
26
+ class_info[:custom][key] = value
27
+ end
28
+
29
+ def custom_add(key, value)
30
+ class_info[:custom] = {} unless class_info[:custom]
31
+ class_info[:custom][key] = class_info[:custom][key] || []
32
+ if value.is_a?(Array)
33
+ class_info[:custom][key] = class_info[:custom][key] + value
34
+ else
35
+ class_info[:custom][key] << value
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,2 @@
1
+ class ApplicationController < ActionController::Base
2
+ end