brick 1.0.152 → 1.0.153
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/extensions.rb +28 -10
- data/lib/brick/frameworks/rails/engine.rb +1 -1
- data/lib/brick/frameworks/rails/form_tags.rb +42 -15
- data/lib/brick/version_number.rb +1 -1
- data/lib/brick.rb +20 -9
- data/lib/generators/brick/install_generator.rb +42 -16
- 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: fc98614593bc4e4931a445801f4f7764c15e6032daf2765f8d78a47f61b7b3a7
|
4
|
+
data.tar.gz: 5b3ae1d718df14101c153b335a66578a5b02771714dedd7ebda1022cadebe482
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 15852e3d59a95d5ac8614d98a44a70796c5494610447505abe61dcd02010c3701dc9ba48da951e4639e4fa14694cfee4c7455c2a0bd63fc613738886ca908b26
|
7
|
+
data.tar.gz: bd5cc34b7c004461af1737dbcb4b746889bd7f4da7d5242c3f341793ed4675c33a50bc61108a6f1e24037585298361f8f4f6ac699a25a72c4ec860f1c272e0ba
|
data/lib/brick/extensions.rb
CHANGED
@@ -1244,25 +1244,38 @@ end
|
|
1244
1244
|
result = if ::Brick.enable_controllers? &&
|
1245
1245
|
is_controller && (plural_class_name = class_name[0..-11]).length.positive?
|
1246
1246
|
# Otherwise now it's up to us to fill in the gaps
|
1247
|
+
controller_class_name = +''
|
1247
1248
|
full_class_name = +''
|
1248
|
-
|
1249
|
+
unless self == Object
|
1250
|
+
controller_class_name << ((split_self_name&.first && split_self_name.join('::')) || self.name)
|
1251
|
+
full_class_name << "::#{controller_class_name}"
|
1252
|
+
controller_class_name << '::'
|
1253
|
+
end
|
1249
1254
|
# (Go over to underscores for a moment so that if we have something come in like VABCsController then the model name ends up as
|
1250
1255
|
# Vabc instead of VABC)
|
1251
1256
|
singular_class_name = ::Brick.namify(plural_class_name, :underscore).singularize.camelize
|
1252
1257
|
full_class_name << "::#{singular_class_name}"
|
1258
|
+
skip_controller = nil
|
1253
1259
|
if plural_class_name == 'BrickOpenapi' ||
|
1254
1260
|
(
|
1255
1261
|
(::Brick.config.add_status || ::Brick.config.add_orphans) &&
|
1256
1262
|
plural_class_name == 'BrickGem'
|
1257
1263
|
) ||
|
1258
|
-
|
1259
|
-
|
1260
|
-
|
1261
|
-
|
1262
|
-
|
1263
|
-
|
1264
|
+
begin
|
1265
|
+
model = self.const_get(full_class_name)
|
1266
|
+
|
1267
|
+
# In the very rare case that we've picked up a MODULE which has the same name as what would be the
|
1268
|
+
# resource's MODEL name, just build out an appropriate auto-model on-the-fly. (RailsDevs code has this in PayCustomer.)
|
1269
|
+
# %%% We don't yet display the code for this new model
|
1270
|
+
if model && !model.is_a?(Class)
|
1271
|
+
model, _code = Object.send(:build_model, relations, model.module_parent, model.module_parent.name, singular_class_name)
|
1272
|
+
end
|
1273
|
+
rescue NameError # If the const_get for the model has failed...
|
1274
|
+
skip_controller = true
|
1275
|
+
# ... then just fall through and allow it to fail when trying to loading the ____Controller class normally.
|
1264
1276
|
end
|
1265
|
-
|
1277
|
+
end
|
1278
|
+
unless skip_controller
|
1266
1279
|
Object.send(:build_controller, self, class_name, plural_class_name, model, relations)
|
1267
1280
|
end
|
1268
1281
|
|
@@ -1475,7 +1488,7 @@ class Object
|
|
1475
1488
|
code << " has_secure_password\n"
|
1476
1489
|
end
|
1477
1490
|
# Accommodate singular or camel-cased table names such as "order_detail" or "OrderDetails"
|
1478
|
-
code << " self.table_name = '#{self.table_name = matching}'\n" if inheritable_name || table_name != matching
|
1491
|
+
code << " self.table_name = '#{self.table_name = matching}'\n" if inheritable_name || self.table_name != matching
|
1479
1492
|
|
1480
1493
|
# Override models backed by a view so they return true for #is_view?
|
1481
1494
|
# (Dynamically-created controllers and view templates for such models will then act in a read-only way)
|
@@ -2225,7 +2238,7 @@ class Object
|
|
2225
2238
|
end
|
2226
2239
|
end
|
2227
2240
|
end
|
2228
|
-
if (upd_hash ||= upd_params).fetch(model.inheritance_column, nil)
|
2241
|
+
if (upd_hash ||= upd_params).fetch(model.inheritance_column, nil)&.strip == ''
|
2229
2242
|
upd_hash[model.inheritance_column] = nil
|
2230
2243
|
end
|
2231
2244
|
obj.send(:update, upd_hash || upd_params)
|
@@ -2485,6 +2498,11 @@ end.class_exec do
|
|
2485
2498
|
::Brick.config.table_name_prefixes[as_tnp] = ar_extension
|
2486
2499
|
end
|
2487
2500
|
end
|
2501
|
+
|
2502
|
+
# Support the followability gem: https://github.com/nejdetkadir/followability
|
2503
|
+
if Object.const_defined?('Followability') && !::Brick.config.table_name_prefixes.key?('followability_')
|
2504
|
+
::Brick.config.table_name_prefixes['followability_'] = 'Followability'
|
2505
|
+
end
|
2488
2506
|
end
|
2489
2507
|
# Load the initializer for the Apartment gem a little early so that if .excluded_models and
|
2490
2508
|
# .default_schema are specified then we can work with non-tenanted models more appropriately
|
@@ -1,7 +1,29 @@
|
|
1
1
|
module Brick::Rails::FormTags
|
2
2
|
# Our super speedy grid
|
3
|
-
def brick_grid(relation, bt_descrip, sequence = nil, inclusions, exclusions,
|
4
|
-
cols, poly_cols, bts, hms_keys, hms_cols)
|
3
|
+
def brick_grid(relation = nil, bt_descrip = nil, sequence = nil, inclusions = nil, exclusions = nil,
|
4
|
+
cols = {}, poly_cols = nil, bts = {}, hms_keys = [], hms_cols = {})
|
5
|
+
# When a relation is not provided, first see if one exists which matches the controller name
|
6
|
+
unless (relation ||= instance_variable_get("@#{controller_name}".to_sym))
|
7
|
+
# Failing that, dig through the instance variables with hopes to find something that is an ActiveRecord::Relation
|
8
|
+
case (collections = _brick_resource_from_iv).length
|
9
|
+
when 0
|
10
|
+
puts '#brick_grid: Not having been provided with a collection to work from, searched through all instance variables to find an ActiveRecord::Relation. None could be found.'
|
11
|
+
return
|
12
|
+
when 1 # If there's only one type match then simply get the first one, hoping that this is what they intended
|
13
|
+
relation = instance_variable_get(iv = (chosen = collections.first).last.first)
|
14
|
+
puts "#brick_grid: Not having been provided with a collection to work from, first tried @#{controller_name}.
|
15
|
+
Failing that, have searched through instance variables and found #{iv} of type #{chosen.first.name}.
|
16
|
+
Running with it!"
|
17
|
+
else
|
18
|
+
myriad = collections.each_with_object([]) { |c, s| c.last.each { |iv| s << "#{iv} (#{c.first.name})" } }
|
19
|
+
puts "#brick_grid: Not having been provided with a collection to work from, first tried @#{controller_name}, and then searched through all instance variables.
|
20
|
+
Found ActiveRecord::Relation objects of multiple types:
|
21
|
+
#{myriad.inspect}
|
22
|
+
Not knowing which of these to render, have erred on the side of caution and simply provided this warning message."
|
23
|
+
return
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
5
27
|
out = "<table id=\"headerTop\"></table>
|
6
28
|
<table id=\"#{relation.table_name.split('.').last}\" class=\"shadow\">
|
7
29
|
<thead><tr>"
|
@@ -14,8 +36,8 @@ module Brick::Rails::FormTags
|
|
14
36
|
col_keys = relation.columns.each_with_object([]) do |col, s|
|
15
37
|
col_name = col.name
|
16
38
|
next if inclusions&.exclude?(col_name) ||
|
17
|
-
(pk.include?(col_name) && [:integer, :uuid].include?(col.type) && !bts
|
18
|
-
::Brick.config.metadata_columns.include?(col_name) || poly_cols
|
39
|
+
(pk.include?(col_name) && [:integer, :uuid].include?(col.type) && !bts&.key?(col_name)) ||
|
40
|
+
::Brick.config.metadata_columns.include?(col_name) || poly_cols&.include?(col_name)
|
19
41
|
|
20
42
|
s << col_name
|
21
43
|
cols[col_name] = col
|
@@ -44,7 +66,8 @@ module Brick::Rails::FormTags
|
|
44
66
|
"x-order=\"#{bt.first.to_s + '"' unless bt[2]}>BT " +
|
45
67
|
bt[1].map { |bt_pair| bt_pair.first.bt_link(bt.first) }.join(' ')
|
46
68
|
else # Normal column
|
47
|
-
|
69
|
+
col_name_humanised = klass.human_attribute_name(col_name, { default: col_name })
|
70
|
+
"x-order=\"#{col_name + '"' if true}>#{col_name_humanised}"
|
48
71
|
end
|
49
72
|
elsif col # HM column
|
50
73
|
options = {}
|
@@ -261,16 +284,7 @@ module Brick::Rails::FormTags
|
|
261
284
|
else
|
262
285
|
# puts "Warning: link_to_brick could not find a class for \"#{controller_path}\" -- consider setting @_brick_model within that controller."
|
263
286
|
# if (hits = res_names.keys & instance_variables.map { |v| v.to_s[1..-1] }).present?
|
264
|
-
links =
|
265
|
-
iv_name = name.to_s[1..-1]
|
266
|
-
case (val = instance_variable_get(name))
|
267
|
-
when ActiveRecord::Relation
|
268
|
-
s[val.klass] << iv_name
|
269
|
-
when ActiveRecord::Base
|
270
|
-
s[val] << iv_name
|
271
|
-
end
|
272
|
-
end
|
273
|
-
if links.length == 1 # If there's only one match then use any text that was supplied
|
287
|
+
if (links = _brick_resource_from_iv(true)).length == 1 # If there's only one match then use any text that was supplied
|
274
288
|
link_to_brick(text || links.first.last.join('/'), links.first.first, **kwargs)
|
275
289
|
else
|
276
290
|
links.each_with_object([]) { |v, s| s << link if link = link_to_brick(v.join('/'), v, **kwargs) }.join(' ').html_safe
|
@@ -278,4 +292,17 @@ module Brick::Rails::FormTags
|
|
278
292
|
end
|
279
293
|
end # link_to_brick
|
280
294
|
|
295
|
+
private
|
296
|
+
|
297
|
+
def _brick_resource_from_iv(trim_ampersand = false)
|
298
|
+
instance_variables.each_with_object(Hash.new { |h, k| h[k] = [] }) do |name, s|
|
299
|
+
iv_name = trim_ampersand ? name.to_s[1..-1] : name
|
300
|
+
case (val = instance_variable_get(name))
|
301
|
+
when ActiveRecord::Relation
|
302
|
+
s[val.klass] << iv_name
|
303
|
+
when ActiveRecord::Base
|
304
|
+
s[val] << iv_name
|
305
|
+
end
|
306
|
+
end
|
307
|
+
end
|
281
308
|
end
|
data/lib/brick/version_number.rb
CHANGED
data/lib/brick.rb
CHANGED
@@ -192,10 +192,17 @@ module Brick
|
|
192
192
|
puts "Based on inclusion in ::Brick.polymorphics, marking association #{full_assoc_name} as being polymorphic."
|
193
193
|
a.options[:polymorphic] = true
|
194
194
|
end
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
195
|
+
unless a.polymorphic? || (!a.belongs_to? && (through = a.options[:through])) ||
|
196
|
+
(a.klass && ::Brick.config.exclude_tables.exclude?(a.klass.table_name) &&
|
197
|
+
(!a.belongs_to? || (same_type = (fk_type = model_cols[a.foreign_key]&.type) == pk_type))
|
198
|
+
)
|
199
|
+
if same_type == false # We really do want to test specifically for false here, and not nil!
|
200
|
+
puts "WARNING:
|
201
|
+
Foreign key column #{a.klass.table_name}.#{a.foreign_key} is #{fk_type}, but the primary key it relates to, #{a.active_record.table_name}.#{a.active_record.primary_key}, is #{pk_type}.
|
202
|
+
These columns should both be of the same type."
|
203
|
+
end
|
204
|
+
next
|
205
|
+
end
|
199
206
|
|
200
207
|
if a.belongs_to?
|
201
208
|
if a.polymorphic?
|
@@ -1375,14 +1382,18 @@ ActiveSupport.on_load(:active_record) do
|
|
1375
1382
|
arsc.class_exec do
|
1376
1383
|
def self.create(connection, callable = nil, &block)
|
1377
1384
|
relation = (callable || block).call ::ActiveRecord::StatementCache::Params.new
|
1378
|
-
bind_map = ::ActiveRecord::StatementCache::BindMap.new(
|
1379
|
-
# AR <= 4.2 uses relation.bind_values
|
1380
|
-
relation.respond_to?(:bound_attributes) ? relation.bound_attributes : relation.bind_values
|
1381
|
-
)
|
1382
1385
|
options = [self, relation.arel]
|
1383
1386
|
options.shift if connection.method(:cacheable_query).arity == 1 # Rails <= 5.0
|
1384
1387
|
query_builder = connection.cacheable_query(*options)
|
1385
|
-
|
1388
|
+
query_builder, binds = query_builder if query_builder.is_a?(Array) # Accommodate AR < 5.2.4
|
1389
|
+
|
1390
|
+
bind_map = ::ActiveRecord::StatementCache::BindMap.new(
|
1391
|
+
# AR <= 4.2 uses relation.bind_values
|
1392
|
+
relation.respond_to?(:bound_attributes) ? relation.bound_attributes : (binds || relation.bind_values)
|
1393
|
+
)
|
1394
|
+
new_options = [query_builder, bind_map]
|
1395
|
+
new_options << relation.klass if binds # Accommodate AR < 5.2.4
|
1396
|
+
new(*new_options)
|
1386
1397
|
end
|
1387
1398
|
end
|
1388
1399
|
end
|
@@ -19,13 +19,25 @@ module Brick
|
|
19
19
|
|
20
20
|
def create_initializer_file
|
21
21
|
is_brick_file = File.exist?(filename = 'config/initializers/brick.rb')
|
22
|
-
if is_brick_file && ::Brick.config.
|
22
|
+
if (is_brick_file && (tnps = ::Brick.config.table_name_prefixes).present?) ||
|
23
|
+
(::Brick.config.schema_behavior[:multitenant]
|
24
|
+
) || !is_brick_file
|
23
25
|
# See if we can make suggestions for additional_references and polymorphic associations
|
24
26
|
resembles_fks = Hash.new { |h, k| h[k] = [] }
|
25
27
|
possible_polymorphics = {}
|
26
|
-
|
27
|
-
|
28
|
-
|
28
|
+
relations = ::Brick.relations
|
29
|
+
if is_brick_file
|
30
|
+
# Need to remove any currently-existing additional_references so that it doesn't cloud the discovery process:
|
31
|
+
::Brick.config.additional_references.each do |ar|
|
32
|
+
if (fks = relations.fetch(ar[0], nil)&.fetch(:fks, nil))
|
33
|
+
fks.delete(fks.find { |k, v| v[:is_bt] && k.start_with?('(brick) ') && v[:fk] == ar[1] }&.first)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
possible_additional_references = relations.each_with_object(Hash.new { |h, k| h[k] = [] }) do |relation, s|
|
38
|
+
this_tnp = tnps&.keys.find { |tnp| relation.first.start_with?(tnp) }
|
39
|
+
model_filename = "app/models/#{ActiveSupport::Inflector.singularize(relation.first)}.rb"
|
40
|
+
relation.last[:cols].each do |col, type|
|
29
41
|
col_down = col.downcase
|
30
42
|
|
31
43
|
if (is_possible_poly = ['character varying', 'text'].include?(type.first))
|
@@ -40,7 +52,7 @@ module Brick
|
|
40
52
|
end
|
41
53
|
is_possible_poly = false if col_down.length < 6 # Was it simply called "type" or something else really short?
|
42
54
|
if is_possible_poly && !File.exist?(model_filename) # Make sure a model file isn't present
|
43
|
-
possible_polymorphics["#{
|
55
|
+
possible_polymorphics["#{relation.first}.#{col_down}"] = "'#{relation.first}.#{col[0..poly_type_cut_length]}'"
|
44
56
|
next
|
45
57
|
end
|
46
58
|
end
|
@@ -66,16 +78,24 @@ module Brick
|
|
66
78
|
col_down = col_down[2..-1]
|
67
79
|
end
|
68
80
|
# This possible key not really a primary key and not yet used as a foreign key?
|
69
|
-
if is_possible && !
|
70
|
-
!
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
relations.fetch(f_table =
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
81
|
+
if is_possible && !relation.last[:pkey].first&.last&.include?(col) &&
|
82
|
+
!relation.last[:fks]&.any? { |_k, v| v[:is_bt] && v[:fk] == col } &&
|
83
|
+
# Starting to look promising ... make sure a model file isn't present
|
84
|
+
!File.exist?(model_filename)
|
85
|
+
if (
|
86
|
+
(relations.fetch(f_table = col_down, nil) ||
|
87
|
+
relations.fetch(f_table = ActiveSupport::Inflector.pluralize(col_down), nil)
|
88
|
+
) && s["#{relation.first}.#{col_down}"] << "['#{relation.first}', '#{col}', '#{f_table}']"
|
89
|
+
) ||
|
90
|
+
(
|
91
|
+
this_tnp && (full_col_down = this_tnp + col_down) &&
|
92
|
+
(relations.fetch(f_table = full_col_down, nil) ||
|
93
|
+
relations.fetch(f_table = ActiveSupport::Inflector.pluralize(full_col_down), nil)
|
94
|
+
) && s["#{relation.first}.#{full_col_down}"] << "['#{relation.first}', '#{col}', '#{f_table}']"
|
95
|
+
)
|
96
|
+
# Found a possible_additional_reference (and set as the last action of the conditional check above)
|
97
|
+
else
|
98
|
+
resembles_fks["#{relation.first}.#{col_down}"] << "#{relation.first}.#{col}"
|
79
99
|
end
|
80
100
|
end
|
81
101
|
end
|
@@ -183,7 +203,13 @@ if ActiveRecord::Base.respond_to?(:brick_select) && !::Brick.initializer_loaded
|
|
183
203
|
# ::Brick.controllers_inherit_from = 'ApplicationController'
|
184
204
|
|
185
205
|
# # When table names have specific prefixes automatically place them in their own module with a table_name_prefix.
|
186
|
-
#
|
206
|
+
#{
|
207
|
+
if tnps
|
208
|
+
"Brick.table_name_prefixes = #{tnps.inspect}"
|
209
|
+
else
|
210
|
+
"# Brick.table_name_prefixes = { 'nav_' => 'Navigation' }"
|
211
|
+
end
|
212
|
+
}
|
187
213
|
|
188
214
|
# # COLUMN SEQUENCING AND INCLUSION / EXCLUSION
|
189
215
|
|
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.153
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lorin Thwaits
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-06-
|
11
|
+
date: 2023-06-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|