brick 1.0.11 → 1.0.14
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.
- checksums.yaml +4 -4
- data/lib/brick/config.rb +8 -0
- data/lib/brick/extensions.rb +97 -32
- data/lib/brick/frameworks/rails/engine.rb +11 -7
- data/lib/brick/version_number.rb +1 -1
- data/lib/brick.rb +7 -0
- data/lib/generators/brick/install_generator.rb +11 -4
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '09600b354a3f70f8680f3dd7a9be9349e6666c013c09a7c9a0dc240e811344ee'
|
4
|
+
data.tar.gz: 0f6ec90f3d38338797a10ec4fc338fae6fdea5b9fddb376c2044fe719afaaa8b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7189638a98c3899d49473a48638dce78da4ed109ed1d4a69185015f9b19428d658fa40ef0f70aa1652a478754b6c1b683a963424ec3e627c56e97b3c2528bba7
|
7
|
+
data.tar.gz: a843f0ec11b7e40bc4cf0a7387ab33e87edd4d9a36de1e24d10c899d969e148015da346fe7b7915f9ffd5a769818e8948de36beb1a368d38a6bb3ab3a97ca7c5
|
data/lib/brick/config.rb
CHANGED
@@ -91,6 +91,14 @@ module Brick
|
|
91
91
|
@mutex.synchronize { @model_descrips = descrips }
|
92
92
|
end
|
93
93
|
|
94
|
+
def sti_namespace_prefixes
|
95
|
+
@mutex.synchronize { @sti_namespace_prefixes ||= {} }
|
96
|
+
end
|
97
|
+
|
98
|
+
def sti_namespace_prefixes=(prefixes)
|
99
|
+
@mutex.synchronize { @sti_namespace_prefixes = prefixes }
|
100
|
+
end
|
101
|
+
|
94
102
|
def skip_database_views
|
95
103
|
@mutex.synchronize { @skip_database_views }
|
96
104
|
end
|
data/lib/brick/extensions.rb
CHANGED
@@ -136,19 +136,67 @@ module ActiveRecord
|
|
136
136
|
|
137
137
|
alias _brick_find_sti_class find_sti_class
|
138
138
|
def find_sti_class(type_name)
|
139
|
-
::Brick.sti_models
|
140
|
-
|
139
|
+
if ::Brick.sti_models.key?(type_name)
|
140
|
+
_brick_find_sti_class(type_name)
|
141
|
+
else
|
142
|
+
# This auto-STI is more of a brute-force approach, building modules where needed
|
143
|
+
# The more graceful alternative is the overload of ActiveSupport::Dependencies#autoload_module! found below
|
144
|
+
::Brick.sti_models[type_name] = { base: self } unless type_name.blank?
|
145
|
+
module_prefixes = type_name.split('::')
|
146
|
+
module_prefixes.unshift('') unless module_prefixes.first.blank?
|
147
|
+
module_name = module_prefixes[0..-2].join('::')
|
148
|
+
if ::Brick.config.sti_namespace_prefixes&.key?(module_name) ||
|
149
|
+
::Brick.config.sti_namespace_prefixes&.key?(module_name[2..-1]) # Take off the leading '::' and see if this matches
|
150
|
+
_brick_find_sti_class(type_name)
|
151
|
+
elsif File.exists?(candidate_file = Rails.root.join('app/models' + module_prefixes.map(&:underscore).join('/') + '.rb'))
|
152
|
+
_brick_find_sti_class(type_name) # Find this STI class normally
|
153
|
+
else
|
154
|
+
# Build missing prefix modules if they don't yet exist
|
155
|
+
this_module = Object
|
156
|
+
module_prefixes[1..-2].each do |module_name|
|
157
|
+
mod = if this_module.const_defined?(module_name)
|
158
|
+
this_module.const_get(module_name)
|
159
|
+
else
|
160
|
+
this_module.const_set(module_name.to_sym, Module.new)
|
161
|
+
end
|
162
|
+
end
|
163
|
+
# Build STI subclass and place it into the namespace module
|
164
|
+
this_module.const_set(module_prefixes.last.to_sym, klass = Class.new(self))
|
165
|
+
klass
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
module ActiveSupport::Dependencies
|
174
|
+
class << self
|
175
|
+
# %%% Probably a little more targeted than other approaches we've taken thusfar
|
176
|
+
# This happens before the whole parent check
|
177
|
+
alias _brick_autoload_module! autoload_module!
|
178
|
+
def autoload_module!(*args)
|
179
|
+
into, const_name, qualified_name, path_suffix = args
|
180
|
+
if (base_class = ::Brick.config.sti_namespace_prefixes&.fetch(into.name, nil)&.constantize)
|
181
|
+
::Brick.sti_models[qualified_name] = { base: base_class }
|
182
|
+
# Build subclass and place it into the specially STI-namespaced module
|
183
|
+
into.const_set(const_name.to_sym, klass = Class.new(base_class))
|
184
|
+
# %%% used to also have: autoload_once_paths.include?(base_path) ||
|
185
|
+
autoloaded_constants << qualified_name unless autoloaded_constants.include?(qualified_name)
|
186
|
+
klass
|
187
|
+
else
|
188
|
+
_brick_autoload_module!(*args)
|
141
189
|
end
|
142
190
|
end
|
143
191
|
end
|
144
192
|
end
|
145
193
|
|
146
|
-
# Object.class_exec do
|
147
194
|
class Object
|
148
195
|
class << self
|
149
196
|
alias _brick_const_missing const_missing
|
150
197
|
def const_missing(*args)
|
151
|
-
return
|
198
|
+
return self.const_get(args.first) if self.const_defined?(args.first)
|
199
|
+
return Object.const_get(args.first) if Object.const_defined?(args.first) unless self == Object
|
152
200
|
|
153
201
|
class_name = args.first.to_s
|
154
202
|
# See if a file is there in the same way that ActiveSupport::Dependencies#load_missing_constant
|
@@ -156,42 +204,58 @@ class Object
|
|
156
204
|
# that is, checking #qualified_name_for with: from_mod, const_name
|
157
205
|
# If we want to support namespacing in the future, might have to utilise something like this:
|
158
206
|
# path_suffix = ActiveSupport::Dependencies.qualified_name_for(Object, args.first).underscore
|
159
|
-
# return
|
207
|
+
# return self._brick_const_missing(*args) if ActiveSupport::Dependencies.search_for_file(path_suffix)
|
160
208
|
# If the file really exists, go and snag it:
|
161
|
-
|
209
|
+
if !(is_found = ActiveSupport::Dependencies.search_for_file(class_name.underscore)) && (filepath = self.name&.split('::'))
|
210
|
+
filepath = (filepath[0..-2] + [class_name]).join('/').underscore + '.rb'
|
211
|
+
end
|
212
|
+
if is_found
|
213
|
+
return self._brick_const_missing(*args)
|
214
|
+
elsif ActiveSupport::Dependencies.search_for_file(filepath) # Last-ditch effort to pick this thing up before we fill in the gaps on our own
|
215
|
+
my_const = parent.const_missing(class_name) # ends up having: MyModule::MyClass
|
216
|
+
return my_const
|
217
|
+
end
|
162
218
|
|
163
219
|
relations = ::Brick.instance_variable_get(:@relations)[ActiveRecord::Base.connection_pool.object_id] || {}
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
220
|
+
is_controllers_enabled = ::Brick.enable_controllers? || (ENV['RAILS_ENV'] || ENV['RACK_ENV']) == 'development'
|
221
|
+
result = if is_controllers_enabled && class_name.end_with?('Controller') && (plural_class_name = class_name[0..-11]).length.positive?
|
222
|
+
# Otherwise now it's up to us to fill in the gaps
|
223
|
+
if (model = ActiveSupport::Inflector.singularize(plural_class_name).constantize)
|
224
|
+
# if it's a controller and no match or a model doesn't really use the same table name, eager load all models and try to find a model class of the right name.
|
225
|
+
build_controller(class_name, plural_class_name, model, relations)
|
226
|
+
end
|
227
|
+
elsif ::Brick.enable_models?
|
228
|
+
# See if a file is there in the same way that ActiveSupport::Dependencies#load_missing_constant
|
229
|
+
# checks for it in ~/.rvm/gems/ruby-2.7.5/gems/activesupport-5.2.6.2/lib/active_support/dependencies.rb
|
230
|
+
plural_class_name = ActiveSupport::Inflector.pluralize(model_name = class_name)
|
231
|
+
singular_table_name = ActiveSupport::Inflector.underscore(model_name)
|
232
|
+
|
233
|
+
# Adjust for STI if we know of a base model for the requested model name
|
234
|
+
table_name = if (base_model = ::Brick.sti_models[model_name]&.fetch(:base, nil))
|
235
|
+
base_model.table_name
|
236
|
+
else
|
237
|
+
ActiveSupport::Inflector.pluralize(singular_table_name)
|
238
|
+
end
|
239
|
+
|
240
|
+
# Maybe, just maybe there's a database table that will satisfy this need
|
241
|
+
if (matching = [table_name, singular_table_name, plural_class_name, model_name].find { |m| relations.key?(m) })
|
242
|
+
build_model(model_name, singular_table_name, table_name, relations, matching)
|
243
|
+
end
|
244
|
+
end
|
188
245
|
if result
|
189
246
|
built_class, code = result
|
190
247
|
puts "\n#{code}"
|
191
248
|
built_class
|
249
|
+
elsif ::Brick.config.sti_namespace_prefixes&.key?(class_name)
|
250
|
+
# binding.pry
|
251
|
+
# module_prefixes = type_name.split('::')
|
252
|
+
# path = self.name.split('::')[0..-2] + []
|
253
|
+
# module_prefixes.unshift('') unless module_prefixes.first.blank?
|
254
|
+
# candidate_file = Rails.root.join('app/models' + module_prefixes.map(&:underscore).join('/') + '.rb')
|
255
|
+
self._brick_const_missing(*args)
|
192
256
|
else
|
193
257
|
puts "MISSING! #{args.inspect} #{table_name}"
|
194
|
-
|
258
|
+
self._brick_const_missing(*args)
|
195
259
|
end
|
196
260
|
end
|
197
261
|
|
@@ -203,7 +267,8 @@ class Object
|
|
203
267
|
|
204
268
|
# Are they trying to use a pluralised class name such as "Employees" instead of "Employee"?
|
205
269
|
if table_name == singular_table_name && !ActiveSupport::Inflector.inflections.uncountable.include?(table_name)
|
206
|
-
|
270
|
+
puts "Warning: Class name for a model that references table \"#{matching}\" should be \"#{ActiveSupport::Inflector.singularize(model_name)}\"."
|
271
|
+
return
|
207
272
|
end
|
208
273
|
if (base_model = ::Brick.sti_models[model_name]&.fetch(:base, nil))
|
209
274
|
is_sti = true
|
@@ -8,9 +8,9 @@ module Brick
|
|
8
8
|
config.brick = ActiveSupport::OrderedOptions.new
|
9
9
|
ActiveSupport.on_load(:before_initialize) do |app|
|
10
10
|
::Brick.enable_models = app.config.brick.fetch(:enable_models, true)
|
11
|
-
::Brick.enable_controllers = app.config.brick.fetch(:enable_controllers,
|
12
|
-
::Brick.enable_views = app.config.brick.fetch(:enable_views,
|
13
|
-
::Brick.enable_routes = app.config.brick.fetch(:enable_routes,
|
11
|
+
::Brick.enable_controllers = app.config.brick.fetch(:enable_controllers, false)
|
12
|
+
::Brick.enable_views = app.config.brick.fetch(:enable_views, false)
|
13
|
+
::Brick.enable_routes = app.config.brick.fetch(:enable_routes, false)
|
14
14
|
::Brick.skip_database_views = app.config.brick.fetch(:skip_database_views, false)
|
15
15
|
|
16
16
|
# Specific database tables and views to omit when auto-creating models
|
@@ -37,7 +37,7 @@ module Brick
|
|
37
37
|
# ====================================
|
38
38
|
# Dynamically create generic templates
|
39
39
|
# ====================================
|
40
|
-
if ::Brick.enable_views?
|
40
|
+
if ::Brick.enable_views? || (ENV['RAILS_ENV'] || ENV['RACK_ENV']) == 'development'
|
41
41
|
ActionView::LookupContext.class_exec do
|
42
42
|
alias :_brick_template_exists? :template_exists?
|
43
43
|
def template_exists?(*args, **options)
|
@@ -209,7 +209,11 @@ function changeout(href, param, value) {
|
|
209
209
|
<% next if k == '#{pk}' || ::Brick.config.metadata_columns.include?(k) %>
|
210
210
|
<td>
|
211
211
|
<% if (bt = bts[k]) %>
|
212
|
-
|
212
|
+
<%# Instead of just 'bt_obj we have to put in all of this junk:
|
213
|
+
# send(\"#\{bt_obj_class = bt[1].name.underscore\}_path\".to_sym, bt_obj.send(bt[1].primary_key.to_sym))
|
214
|
+
# Otherwise we get stuff like:
|
215
|
+
# ActionView::Template::Error (undefined method `vehicle_path' for #<ActionView::Base:0x0000000033a888>) %>
|
216
|
+
<%= bt_obj = bt[1].find_by(bt.last => val); link_to(bt_obj.brick_descrip, send(\"#\{bt_obj_class = bt[1].name.underscore\}_path\".to_sym, bt_obj.send(bt[1].primary_key.to_sym))) if bt_obj %>
|
213
217
|
<% else %>
|
214
218
|
<%= val %>
|
215
219
|
<% end %>
|
@@ -244,7 +248,7 @@ function changeout(href, param, value) {
|
|
244
248
|
</th>
|
245
249
|
<td>
|
246
250
|
<% if (bt = bts[k]) %>
|
247
|
-
<%= bt_obj = bt[1].find_by(bt.last => val); link_to(bt_obj.brick_descrip, bt_obj) if bt_obj %>
|
251
|
+
<%= bt_obj = bt[1].find_by(bt.last => val); link_to(bt_obj.brick_descrip, send(\"#\{bt_obj_class = bt[1].name.underscore\}_path\".to_sym, bt_obj.send(bt[1].primary_key.to_sym))) if bt_obj %>
|
248
252
|
<% else %>
|
249
253
|
<%= val %>
|
250
254
|
<% end %>
|
@@ -279,7 +283,7 @@ function changeout(href, param, value) {
|
|
279
283
|
end
|
280
284
|
end
|
281
285
|
|
282
|
-
if ::Brick.enable_routes?
|
286
|
+
if ::Brick.enable_routes? || (ENV['RAILS_ENV'] || ENV['RACK_ENV']) == 'development'
|
283
287
|
ActionDispatch::Routing::RouteSet.class_exec do
|
284
288
|
alias _brick_finalize_routeset! finalize!
|
285
289
|
def finalize!(*args, **options)
|
data/lib/brick/version_number.rb
CHANGED
data/lib/brick.rb
CHANGED
@@ -228,6 +228,13 @@ module Brick
|
|
228
228
|
Brick.config.model_descrips = descrips
|
229
229
|
end
|
230
230
|
|
231
|
+
# Module prefixes to build out and associate with specific base STI models
|
232
|
+
# @api public
|
233
|
+
def sti_namespace_prefixes=(snp)
|
234
|
+
Brick.config.sti_namespace_prefixes = snp
|
235
|
+
end
|
236
|
+
|
237
|
+
|
231
238
|
# Returns Brick's `::Gem::Version`, convenient for comparisons. This is
|
232
239
|
# recommended over `::Brick::VERSION::STRING`.
|
233
240
|
#
|
@@ -80,11 +80,13 @@ module Brick
|
|
80
80
|
# # Settings for the Brick gem
|
81
81
|
# # (By default this auto-creates models, controllers, views, and routes on-the-fly.)
|
82
82
|
|
83
|
-
# # Normally
|
84
|
-
#
|
83
|
+
# # Normally all are enabled in development mode, and for security reasons only models are enabled in production
|
84
|
+
# # and test. This allows you to either (a) turn off models entirely, or (b) enable controllers, views, and routes
|
85
|
+
# # in production.
|
86
|
+
# Brick.enable_routes = true # Setting this to \"false\" will disable routes in development
|
85
87
|
# Brick.enable_models = false
|
86
|
-
# Brick.enable_controllers = false
|
87
|
-
# Brick.enable_views = false
|
88
|
+
# Brick.enable_controllers = true # Setting this to \"false\" will disable controllers in development
|
89
|
+
# Brick.enable_views = true # Setting this to \"false\" will disable views in development
|
88
90
|
|
89
91
|
# # By default models are auto-created for database views, and set to be read-only. This can be skipped.
|
90
92
|
# Brick.skip_database_views = true
|
@@ -133,6 +135,11 @@ module Brick
|
|
133
135
|
# # user, then you can use model_descrips like this, putting expressions with property references in square brackets:
|
134
136
|
# Brick.model_descrips = { 'User' => '[profile.firstname] [profile.lastname]' }
|
135
137
|
|
138
|
+
# # Module prefixes to be built out and associated when new subclasses are requested for specific base STI models
|
139
|
+
# # (If this setting exists then only these subclasses will be honoured, and other requested )
|
140
|
+
# # The prefixed :: here on the sample module name LetterTemplates is optional. Used here for clarity.
|
141
|
+
# Brick.sti_namespace_prefixes = { '::LetterTemplates' => 'LetterTemplate' }
|
142
|
+
|
136
143
|
# # If a default route is not supplied, Brick attempts to find the most \"central\" table and wires up the default
|
137
144
|
# # route to go to the :index action for what would be a controller for that table. You can specify any controller
|
138
145
|
# # name and action you wish in order to override this and have that be the default route when none other has been
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: brick
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.14
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lorin Thwaits
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-03-
|
11
|
+
date: 2022-03-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|