brick 1.0.152 → 1.0.153
Sign up to get free protection for your applications and to get access to all the features.
- 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
|