brick 1.0.13 → 1.0.14
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/brick/config.rb +8 -0
- data/lib/brick/extensions.rb +91 -46
- data/lib/brick/version_number.rb +1 -1
- data/lib/brick.rb +7 -0
- data/lib/generators/brick/install_generator.rb +5 -0
- metadata +1 -1
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,38 +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
|
-
module_prefixes = type_name.split('::')
|
141
|
-
module_prefixes.unshift('') unless module_prefixes.first.blank?
|
142
|
-
candidate_file = Rails.root.join('app/models' + module_prefixes.map(&:underscore).join('/') + '.rb')
|
143
|
-
if File.exists?(candidate_file)
|
144
|
-
# Find this STI class normally
|
139
|
+
if ::Brick.sti_models.key?(type_name)
|
145
140
|
_brick_find_sti_class(type_name)
|
146
141
|
else
|
147
|
-
#
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
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
|
155
166
|
end
|
156
|
-
# Build missing prefix modules if they don't yet exist
|
157
|
-
this_module.const_set(module_prefixes.last.to_sym, klass = Class.new(self))
|
158
|
-
klass
|
159
167
|
end
|
160
168
|
end
|
161
169
|
end
|
162
170
|
end
|
163
171
|
end
|
164
172
|
|
165
|
-
|
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)
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
166
194
|
class Object
|
167
195
|
class << self
|
168
196
|
alias _brick_const_missing const_missing
|
169
197
|
def const_missing(*args)
|
170
|
-
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
|
171
200
|
|
172
201
|
class_name = args.first.to_s
|
173
202
|
# See if a file is there in the same way that ActiveSupport::Dependencies#load_missing_constant
|
@@ -175,43 +204,58 @@ class Object
|
|
175
204
|
# that is, checking #qualified_name_for with: from_mod, const_name
|
176
205
|
# If we want to support namespacing in the future, might have to utilise something like this:
|
177
206
|
# path_suffix = ActiveSupport::Dependencies.qualified_name_for(Object, args.first).underscore
|
178
|
-
# return
|
207
|
+
# return self._brick_const_missing(*args) if ActiveSupport::Dependencies.search_for_file(path_suffix)
|
179
208
|
# If the file really exists, go and snag it:
|
180
|
-
|
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
|
181
218
|
|
182
219
|
relations = ::Brick.instance_variable_get(:@relations)[ActiveRecord::Base.connection_pool.object_id] || {}
|
183
220
|
is_controllers_enabled = ::Brick.enable_controllers? || (ENV['RAILS_ENV'] || ENV['RACK_ENV']) == 'development'
|
184
221
|
result = if is_controllers_enabled && class_name.end_with?('Controller') && (plural_class_name = class_name[0..-11]).length.positive?
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
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
|
208
245
|
if result
|
209
246
|
built_class, code = result
|
210
247
|
puts "\n#{code}"
|
211
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)
|
212
256
|
else
|
213
257
|
puts "MISSING! #{args.inspect} #{table_name}"
|
214
|
-
|
258
|
+
self._brick_const_missing(*args)
|
215
259
|
end
|
216
260
|
end
|
217
261
|
|
@@ -223,7 +267,8 @@ class Object
|
|
223
267
|
|
224
268
|
# Are they trying to use a pluralised class name such as "Employees" instead of "Employee"?
|
225
269
|
if table_name == singular_table_name && !ActiveSupport::Inflector.inflections.uncountable.include?(table_name)
|
226
|
-
|
270
|
+
puts "Warning: Class name for a model that references table \"#{matching}\" should be \"#{ActiveSupport::Inflector.singularize(model_name)}\"."
|
271
|
+
return
|
227
272
|
end
|
228
273
|
if (base_model = ::Brick.sti_models[model_name]&.fetch(:base, nil))
|
229
274
|
is_sti = true
|
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
|
#
|
@@ -135,6 +135,11 @@ module Brick
|
|
135
135
|
# # user, then you can use model_descrips like this, putting expressions with property references in square brackets:
|
136
136
|
# Brick.model_descrips = { 'User' => '[profile.firstname] [profile.lastname]' }
|
137
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
|
+
|
138
143
|
# # If a default route is not supplied, Brick attempts to find the most \"central\" table and wires up the default
|
139
144
|
# # route to go to the :index action for what would be a controller for that table. You can specify any controller
|
140
145
|
# # name and action you wish in order to override this and have that be the default route when none other has been
|