brick 1.0.109 → 1.0.111
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 +54 -8
- data/lib/brick/frameworks/rails/engine.rb +69 -53
- data/lib/brick/frameworks/rails/form_tags.rb +5 -3
- data/lib/brick/version_number.rb +1 -1
- data/lib/brick.rb +50 -32
- 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: cb97e4a946526ed99a24e67b1e65d5f6490a40c97dc170dd0680166b087d1ccb
|
4
|
+
data.tar.gz: 48d9c4f2afcd737d9a857f8c771448639c1b0d2d568dc966bbe4b85a97cb4610
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 383d9996affbbd4fa049ab125490879143299a5477e98f921d450ea6b5b466d66a4cd210aac8db9c105a6eaf5f10eae8ac181d84d78fb6fc0b4c4151ac9dcee3
|
7
|
+
data.tar.gz: b9902fc959b0de870ef5c402fe75e76d939d0c7c5abc7b8d3c16451b87f56929eb6e329153c6b5697936f10228752ba3b2f5f2a7de6aa5c9c77c105c34dd2cfa
|
data/lib/brick/extensions.rb
CHANGED
@@ -261,9 +261,16 @@ module ActiveRecord
|
|
261
261
|
assoc_html_name ? "#{assoc_name}-#{link}".html_safe : link
|
262
262
|
end
|
263
263
|
|
264
|
-
|
264
|
+
# Providing a relation object allows auto-modules built from table name prefixes to work
|
265
|
+
def self._brick_index(mode = nil, separator = '_', relation = nil)
|
265
266
|
tbl_parts = ((mode == :singular) ? table_name.singularize : table_name).split('.')
|
266
267
|
tbl_parts.shift if ::Brick.apartment_multitenant && tbl_parts.length > 1 && tbl_parts.first == ::Brick.apartment_default_tenant
|
268
|
+
if (aps = relation&.fetch(:auto_prefixed_schema, nil)) && tbl_parts.last.start_with?(aps)
|
269
|
+
last_part = tbl_parts.last[aps.length..-1]
|
270
|
+
aps = aps[0..-2] if aps[-1] == '_'
|
271
|
+
tbl_parts[-1] = aps
|
272
|
+
tbl_parts << last_part
|
273
|
+
end
|
267
274
|
tbl_parts.unshift(::Brick.config.path_prefix) if ::Brick.config.path_prefix
|
268
275
|
index = tbl_parts.map(&:underscore).join(separator)
|
269
276
|
# Rails applies an _index suffix to that route when the resource name is singular
|
@@ -1005,7 +1012,8 @@ Module.class_exec do
|
|
1005
1012
|
|
1006
1013
|
# MODULE
|
1007
1014
|
elsif (::Brick.enable_models? || ::Brick.enable_controllers?) && # Schema match?
|
1008
|
-
|
1015
|
+
# %%% This works for Person::Person -- but also limits us to not being able to allow more than one level of namespacing
|
1016
|
+
(base_module == Object || (camelize_prefix && base_module == Object.const_get(camelize_prefix))) &&
|
1009
1017
|
(schema_name = [(singular_table_name = class_name.underscore),
|
1010
1018
|
(table_name = singular_table_name.pluralize),
|
1011
1019
|
::Brick.is_oracle ? class_name.upcase : class_name,
|
@@ -1437,7 +1445,7 @@ class Object
|
|
1437
1445
|
is_postgres = ActiveRecord::Base.connection.adapter_name == 'PostgreSQL'
|
1438
1446
|
is_mysql = ['Mysql2', 'Trilogy'].include?(ActiveRecord::Base.connection.adapter_name)
|
1439
1447
|
|
1440
|
-
code = +"class #{class_name} < #{controller_base&.name || 'ApplicationController'}\n"
|
1448
|
+
code = +"class #{namespace}::#{class_name} < #{controller_base&.name || 'ApplicationController'}\n"
|
1441
1449
|
built_controller = Class.new(controller_base || ActionController::Base) do |new_controller_class|
|
1442
1450
|
(namespace || Object).const_set(class_name.to_sym, new_controller_class)
|
1443
1451
|
|
@@ -2011,6 +2019,21 @@ end.class_exec do
|
|
2011
2019
|
# .default_schema are specified then we can work with non-tenanted models more appropriately
|
2012
2020
|
if (apartment = Object.const_defined?('Apartment')) &&
|
2013
2021
|
File.exist?(apartment_initializer = ::Rails.root.join('config/initializers/apartment.rb'))
|
2022
|
+
require 'apartment/adapters/abstract_adapter'
|
2023
|
+
Apartment::Adapters::AbstractAdapter.class_exec do
|
2024
|
+
if instance_methods.include?(:process_excluded_models)
|
2025
|
+
def process_excluded_models
|
2026
|
+
# All other models will share a connection (at Apartment.connection_class) and we can modify at will
|
2027
|
+
Apartment.excluded_models.each do |excluded_model|
|
2028
|
+
begin
|
2029
|
+
process_excluded_model(excluded_model)
|
2030
|
+
rescue NameError => e
|
2031
|
+
(@bad_models ||= []) << excluded_model
|
2032
|
+
end
|
2033
|
+
end
|
2034
|
+
end
|
2035
|
+
end
|
2036
|
+
end
|
2014
2037
|
unless @_apartment_loaded
|
2015
2038
|
load apartment_initializer
|
2016
2039
|
@_apartment_loaded = true
|
@@ -2049,13 +2072,27 @@ end.class_exec do
|
|
2049
2072
|
schema = possible_schema
|
2050
2073
|
orig_schema = ActiveRecord::Base.execute_sql('SELECT current_schemas(true)').first['current_schemas'][1..-2].split(',')
|
2051
2074
|
ActiveRecord::Base.execute_sql("SET SEARCH_PATH = ?", schema)
|
2052
|
-
|
2053
|
-
|
2054
|
-
|
2075
|
+
# When testing, just find the most recently-created schema
|
2076
|
+
elsif begin
|
2077
|
+
Rails.env == 'test' ||
|
2078
|
+
ActiveRecord::Base.execute_sql("SELECT value FROM ar_internal_metadata WHERE key='environment';").first&.fetch('value', nil) == 'test'
|
2079
|
+
rescue
|
2080
|
+
end
|
2081
|
+
::Brick.default_schema = ::Brick.apartment_default_tenant
|
2082
|
+
::Brick.test_schema = schema = ::Brick.db_schemas.to_a.sort { |a, b| b.last[:dt] <=> a.last[:dt] }.first.first
|
2083
|
+
if possible_schema.blank?
|
2084
|
+
puts "While running tests, using the most recently-created schema, #{schema}."
|
2085
|
+
else
|
2086
|
+
puts "While running tests, had noticed in the brick.rb initializer that the line \"::Brick.schema_behavior = ...\" refers to a schema called \"#{possible_schema}\" which does not exist. Reading table structure from the most recently-created schema, #{schema}."
|
2087
|
+
end
|
2055
2088
|
orig_schema = ActiveRecord::Base.execute_sql('SELECT current_schemas(true)').first['current_schemas'][1..-2].split(',')
|
2089
|
+
::Brick.config.schema_behavior = { multitenant: {} } # schema_to_analyse: [schema]
|
2056
2090
|
ActiveRecord::Base.execute_sql("SET SEARCH_PATH = ?", schema)
|
2057
2091
|
else
|
2058
2092
|
puts "*** In the brick.rb initializer the line \"::Brick.schema_behavior = ...\" refers to schema(s) called #{possible_schemas.map { |s| "\"#{s}\"" }.join(', ')}. No mentioned schema exists. ***"
|
2093
|
+
if ::Brick.db_schemas.key?(::Brick.apartment_default_tenant)
|
2094
|
+
::Brick.default_schema = schema = ::Brick.apartment_default_tenant
|
2095
|
+
end
|
2059
2096
|
end
|
2060
2097
|
end
|
2061
2098
|
when 'Mysql2', 'Trilogy'
|
@@ -2272,11 +2309,20 @@ ORDER BY 1, 2, c.internal_column_id, acc.position"
|
|
2272
2309
|
schema_names.shift if ::Brick.apartment_multitenant && schema_names.first == ::Brick.apartment_default_tenant
|
2273
2310
|
v[:schema] = schema_names.join('.') unless schema_names.empty?
|
2274
2311
|
# %%% If more than one schema has the same table name, will need to add a schema name prefix to have uniqueness
|
2275
|
-
v[:resource] = rel_name.last
|
2276
2312
|
if (singular = rel_name.last.singularize).blank?
|
2277
2313
|
singular = rel_name.last
|
2278
2314
|
end
|
2279
|
-
|
2315
|
+
name_parts = if (tnp = ::Brick.config.table_name_prefixes
|
2316
|
+
.find { |k1, _v1| singular.start_with?(k1) && singular.length > k1.length }
|
2317
|
+
).present?
|
2318
|
+
v[:auto_prefixed_schema] = tnp.first
|
2319
|
+
v[:resource] = rel_name.last[(tnp_length = tnp.first.length)..-1]
|
2320
|
+
[tnp.last, singular[tnp_length..-1]]
|
2321
|
+
else
|
2322
|
+
v[:resource] = rel_name.last
|
2323
|
+
[singular]
|
2324
|
+
end
|
2325
|
+
v[:class_name] = (schema_names + name_parts).map(&:camelize).join('::')
|
2280
2326
|
end
|
2281
2327
|
::Brick.load_additional_references if ::Brick.initializer_loaded
|
2282
2328
|
|
@@ -10,10 +10,13 @@ module Brick
|
|
10
10
|
if (param === undefined || param === null || param === -1) {
|
11
11
|
hrefParts = hrefParts[0].split(\"://\");
|
12
12
|
var pathParts = hrefParts[hrefParts.length - 1].split(\"/\").filter(function (pp) {return pp !== \"\";});
|
13
|
-
if (value === undefined)
|
13
|
+
if (value === undefined) {
|
14
14
|
// A couple possibilities if it's namespaced, starting with two parts in the path -- and then try just one
|
15
|
-
|
16
|
-
|
15
|
+
if (pathParts.length > 3)
|
16
|
+
return [pathParts.slice(1, 4).join('/'), pathParts.slice(1, 3).join('/')];
|
17
|
+
else
|
18
|
+
return [pathParts.slice(1, 3).join('/'), pathParts[1]];
|
19
|
+
} else {
|
17
20
|
var queryString = param ? \"?\" + params.join(\"&\") : \"\";
|
18
21
|
return hrefParts[0] + \"://\" + pathParts[0] + \"/\" + value + queryString;
|
19
22
|
}
|
@@ -33,11 +36,12 @@ module Brick
|
|
33
36
|
// This PageTransitionEvent fires when the page first loads, as well as after any other history
|
34
37
|
// transition such as when using the browser's Back and Forward buttons.
|
35
38
|
window.addEventListener(\"pageshow\", linkSchemas);
|
36
|
-
var brickSchema
|
39
|
+
var brickSchema,
|
40
|
+
brickTestSchema;
|
37
41
|
function linkSchemas() {
|
38
42
|
var schemaSelect = document.getElementById(\"schema\");
|
39
43
|
var tblSelect = document.getElementById(\"tbl\");
|
40
|
-
if (tblSelect) { // Always present
|
44
|
+
if (tblSelect) { // Always present for Brick pages
|
41
45
|
// Used to be: var i = # {::Brick.config.path_prefix ? '0' : 'schemaSelect ? 1 : 0'},
|
42
46
|
var changeoutList = changeout(location.href);
|
43
47
|
for (var i = 0; i < changeoutList.length; ++i) {
|
@@ -50,32 +54,32 @@ function linkSchemas() {
|
|
50
54
|
if (brickSchema) lhr = changeout(lhr, \"_brick_schema\", schemaSelect.value);
|
51
55
|
location.href = lhr;
|
52
56
|
});
|
53
|
-
}
|
54
57
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
58
|
+
if (schemaSelect) { // First drop-down is only present if multitenant
|
59
|
+
if (brickSchema = changeout(location.href, \"_brick_schema\")) {
|
60
|
+
[... document.getElementsByTagName(\"A\")].forEach(function (a) { a.href = changeout(a.href, \"_brick_schema\", brickSchema); });
|
61
|
+
}
|
62
|
+
if (schemaSelect.options.length > 1) {
|
63
|
+
schemaSelect.value = brickSchema || brickTestSchema || \"public\";
|
64
|
+
schemaSelect.addEventListener(\"change\", function () {
|
65
|
+
// If there's an ID then remove it (trim after selected table)
|
66
|
+
location.href = changeout(location.href, \"_brick_schema\", this.value, tblSelect.value);
|
67
|
+
});
|
68
|
+
}
|
65
69
|
}
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
form.
|
72
|
-
|
73
|
-
|
74
|
-
|
70
|
+
tblSelect.focus();
|
71
|
+
|
72
|
+
[... document.getElementsByTagName(\"FORM\")].forEach(function (form) {
|
73
|
+
if (brickSchema)
|
74
|
+
form.action = changeout(form.action, \"_brick_schema\", brickSchema);
|
75
|
+
form.addEventListener('submit', function (ev) {
|
76
|
+
[... ev.target.getElementsByTagName(\"SELECT\")].forEach(function (select) {
|
77
|
+
if (select.value === \"^^^brick_NULL^^^\") select.value = null;
|
78
|
+
});
|
79
|
+
return true;
|
75
80
|
});
|
76
|
-
return true;
|
77
81
|
});
|
78
|
-
}
|
82
|
+
}
|
79
83
|
};
|
80
84
|
"
|
81
85
|
|
@@ -187,7 +191,8 @@ function linkSchemas() {
|
|
187
191
|
s[r.name[0..-9]] = nil if r.name.end_with?('Resource')
|
188
192
|
end
|
189
193
|
::Brick.relations.each do |k, v|
|
190
|
-
unless existing.key?(class_name = v[:class_name]) || Brick.config.exclude_tables.include?(k) ||
|
194
|
+
unless existing.key?(class_name = v[:class_name]) || Brick.config.exclude_tables.include?(k) ||
|
195
|
+
class_name.blank? || class_name.include?('::')
|
191
196
|
Object.const_get("#{class_name}Resource")
|
192
197
|
end
|
193
198
|
end
|
@@ -355,15 +360,11 @@ window.addEventListener(\"popstate\", linkSchemas);
|
|
355
360
|
(is_status = ::Brick.config.add_status && args[0..1] == ['status', ['brick_gem']]) ||
|
356
361
|
(is_orphans = ::Brick.config.add_orphans && args[0..1] == ['orphans', ['brick_gem']]) ||
|
357
362
|
(is_crosstab = args[0..1] == ['crosstab', ['brick_gem']])
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
return possible_template
|
362
|
-
end
|
363
|
-
rescue
|
363
|
+
begin
|
364
|
+
if (possible_template = _brick_find_template(*args, **options))
|
365
|
+
return possible_template
|
364
366
|
end
|
365
|
-
|
366
|
-
return possible_template
|
367
|
+
rescue
|
367
368
|
end
|
368
369
|
# Used to also have: ActionView.version < ::Gem::Version.new('5.0') &&
|
369
370
|
model_name = (args[1].is_a?(Array) ? set_brick_model(args) : nil)&.name
|
@@ -452,11 +453,22 @@ window.addEventListener(\"popstate\", linkSchemas);
|
|
452
453
|
# %%% If we are not auto-creating controllers (or routes) then omit by default, and if enabled anyway, such as in a development
|
453
454
|
# environment or whatever, then get either the controllers or routes list instead
|
454
455
|
prefix = "#{::Brick.config.path_prefix}/" if ::Brick.config.path_prefix
|
455
|
-
table_options =
|
456
|
-
if
|
457
|
-
|
456
|
+
table_options = ::Brick.relations.each_with_object({}) do |rel, s|
|
457
|
+
next if ::Brick.config.exclude_tables.include?(rel.first)
|
458
|
+
|
459
|
+
tbl_parts = rel.first.split('.')
|
460
|
+
if (aps = rel.last.fetch(:auto_prefixed_schema, nil))
|
461
|
+
tbl_parts << tbl_parts.last[aps.length..-1]
|
462
|
+
aps = aps[0..-2] if aps[-1] == '_'
|
463
|
+
tbl_parts[-2] = aps
|
458
464
|
end
|
459
|
-
|
465
|
+
if tbl_parts.first == apartment_default_schema
|
466
|
+
tbl_parts.shift
|
467
|
+
end
|
468
|
+
# %%% When table_name_prefixes are use then during rendering empty non-TNP
|
469
|
+
# entries get added at some point when an attempt is made to find the table.
|
470
|
+
# Will have to hunt that down at some point.
|
471
|
+
s[tbl_parts.join('.')] = nil unless rel.last[:cols].empty?
|
460
472
|
end.keys.sort.each_with_object(+'') do |v, s|
|
461
473
|
s << "<option value=\"#{prefix}#{v.underscore.gsub('.', '/')}\">#{v}</option>"
|
462
474
|
end.html_safe
|
@@ -836,8 +848,9 @@ document.querySelectorAll(\"input[type=submit][data-confirm]\").forEach(function
|
|
836
848
|
});
|
837
849
|
});
|
838
850
|
|
839
|
-
#{JS_CHANGEOUT}
|
840
|
-
|
851
|
+
#{JS_CHANGEOUT}#{
|
852
|
+
"\nbrickTestSchema = \"#{::Brick.test_schema}\";" if ::Brick.test_schema
|
853
|
+
}
|
841
854
|
// Snag first TR for sticky header
|
842
855
|
var grid = document.getElementById(\"#{table_name}\");
|
843
856
|
#{table_name}HtColumns = grid && [grid.getElementsByTagName(\"TR\")[0]];
|
@@ -881,7 +894,8 @@ if (grid) {
|
|
881
894
|
// });
|
882
895
|
}
|
883
896
|
function setHeaderSizes() {
|
884
|
-
|
897
|
+
if (grid.clientWidth > window.outerWidth)
|
898
|
+
document.getElementById(\"titleBox\").style.width = grid.clientWidth;
|
885
899
|
// console.log(\"start\");
|
886
900
|
// See if the headerTop is already populated
|
887
901
|
// %%% Grab the TRs from headerTop, clear it out, do this stuff, add them back
|
@@ -1136,12 +1150,13 @@ erDiagram
|
|
1136
1150
|
<td><h1><%= td_count = 2
|
1137
1151
|
model.name %></h1></td>
|
1138
1152
|
<td id=\"imgErd\" title=\"Show ERD\"></td>
|
1139
|
-
<% if Object.const_defined?('Avo') && ::Avo.respond_to?(:railtie_namespace)
|
1153
|
+
<% if Object.const_defined?('Avo') && ::Avo.respond_to?(:railtie_namespace) && model.name.exclude?('::')
|
1140
1154
|
td_count += 1 %>
|
1141
1155
|
<td><%= link_to_brick(
|
1142
1156
|
avo_svg,
|
1143
|
-
{ index_proc: Proc.new do |avo_model|
|
1144
|
-
|
1157
|
+
{ index_proc: Proc.new do |avo_model, relation|
|
1158
|
+
path_helper = \"resources_#\{relation.fetch(:auto_prefixed_schema, nil)}#\{model.model_name.route_key}_path\".to_sym
|
1159
|
+
::Avo.railtie_routes_url_helpers.send(path_helper) if ::Avo.railtie_routes_url_helpers.respond_to?(path_helper)
|
1145
1160
|
end,
|
1146
1161
|
title: \"#\{model.name} in Avo\" }
|
1147
1162
|
) %></td>
|
@@ -1328,8 +1343,9 @@ erDiagram
|
|
1328
1343
|
<% if Object.const_defined?('Avo') && ::Avo.respond_to?(:railtie_namespace) %>
|
1329
1344
|
<td><%= link_to_brick(
|
1330
1345
|
avo_svg,
|
1331
|
-
{ show_proc: Proc.new do |obj|
|
1332
|
-
|
1346
|
+
{ show_proc: Proc.new do |obj, relation|
|
1347
|
+
path_helper = \"resources_#\{relation.fetch(:auto_prefixed_schema, nil)}#\{obj.class.base_class.model_name.singular_route_key}_path\".to_sym
|
1348
|
+
::Avo.railtie_routes_url_helpers.send(path_helper, obj) if ::Avo.railtie_routes_url_helpers.respond_to?(path_helper)
|
1333
1349
|
end,
|
1334
1350
|
title: \"#\{page_title} in Avo\" }
|
1335
1351
|
) %></td>
|
@@ -1408,8 +1424,8 @@ end
|
|
1408
1424
|
\"<span class=\\\"orphan\\\">Orphaned ID: #\{val}</span>\".html_safe
|
1409
1425
|
end %>
|
1410
1426
|
<% else
|
1411
|
-
col_type = col
|
1412
|
-
case (col_type ||= col
|
1427
|
+
col_type = col&.sql_type == 'geography' ? col.sql_type : col&.type
|
1428
|
+
case (col_type ||= col&.sql_type)
|
1413
1429
|
when :string, :text %>
|
1414
1430
|
<% if is_bcrypt?(val) # || .readonly?
|
1415
1431
|
is_revert = false %>
|
@@ -1489,9 +1505,9 @@ end
|
|
1489
1505
|
# association that points to an STI model then filtering for the __able_type column is done
|
1490
1506
|
# with a .where(). And the polymorphic class name it points to is the base class name of
|
1491
1507
|
# the STI model instead of its subclass.
|
1492
|
-
|
1493
|
-
|
1494
|
-
|
1508
|
+
poly_type = #{poly_type.inspect}
|
1509
|
+
if poly_type && @#{obj_name}.respond_to?(:#{@_brick_model.inheritance_column}) &&
|
1510
|
+
(base_type = collection.where_values_hash[poly_type])
|
1495
1511
|
collection = collection.rewhere(poly_type => [base_type, @#{obj_name}.#{@_brick_model.inheritance_column}])
|
1496
1512
|
end"
|
1497
1513
|
end
|
@@ -162,8 +162,9 @@ module Brick::Rails::FormTags
|
|
162
162
|
@_brick_model
|
163
163
|
# If not provided, do a best-effort to automatically determine the resource class or object
|
164
164
|
filter_parts = []
|
165
|
+
rel_name = nil
|
165
166
|
klass_or_obj ||= begin
|
166
|
-
klass, sti_type = ::Brick.ctrl_to_klass(controller_path)
|
167
|
+
klass, sti_type, rel_name = ::Brick.ctrl_to_klass(controller_path)
|
167
168
|
if klass
|
168
169
|
type_col = klass.inheritance_column # Usually 'type'
|
169
170
|
filter_parts << "#{type_col}=#{sti_type}" if sti_type && klass.column_names.include?(type_col)
|
@@ -200,13 +201,14 @@ module Brick::Rails::FormTags
|
|
200
201
|
end
|
201
202
|
filter = "?#{filter_parts.join('&')}" if filter_parts.present?
|
202
203
|
app_routes = Rails.application.routes # In case we're operating in another engine, reference the application since Brick routes are placed there.
|
204
|
+
relation = ::Brick.relations.fetch(rel_name || args.first.table_name, nil)
|
203
205
|
if (klass_or_obj&.is_a?(Class) && klass_or_obj < ActiveRecord::Base) ||
|
204
206
|
(klass_or_obj&.is_a?(ActiveRecord::Base) && klass_or_obj.new_record? && (klass_or_obj = klass_or_obj.class))
|
205
|
-
path = (proc = kwargs[:index_proc]) ? proc.call(klass_or_obj) : "#{app_routes.path_for(controller: klass_or_obj.base_class._brick_index(nil, '/'), action: :index)}#{filter}"
|
207
|
+
path = (proc = kwargs[:index_proc]) ? proc.call(klass_or_obj, relation) : "#{app_routes.path_for(controller: klass_or_obj.base_class._brick_index(nil, '/', relation), action: :index)}#{filter}"
|
206
208
|
lt_args = [text || "Index for #{klass_or_obj.name.pluralize}", path]
|
207
209
|
else
|
208
210
|
# If there are multiple incoming parameters then last one is probably the actual ID, and first few might be some nested tree of stuff leading up to it
|
209
|
-
path = (proc = kwargs[:show_proc]) ? proc.call(klass_or_obj) : "#{app_routes.path_for(controller: klass_or_obj.class.base_class._brick_index(nil, '/'), action: :show, id: klass_or_obj)}#{filter}"
|
211
|
+
path = (proc = kwargs[:show_proc]) ? proc.call(klass_or_obj, relation) : "#{app_routes.path_for(controller: klass_or_obj.class.base_class._brick_index(nil, '/', relation), action: :show, id: klass_or_obj)}#{filter}"
|
210
212
|
lt_args = [text || "Show this #{klass_or_obj.class.name}", path]
|
211
213
|
end
|
212
214
|
kwargs.delete(:visited)
|
data/lib/brick/version_number.rb
CHANGED
data/lib/brick.rb
CHANGED
@@ -135,7 +135,8 @@ module Brick
|
|
135
135
|
@existing_stis ||= Brick.config.sti_namespace_prefixes.each_with_object({}) { |snp, s| s[snp.first[2..-1]] = snp.last unless snp.first.end_with?('::') }
|
136
136
|
end
|
137
137
|
|
138
|
-
attr_accessor :default_schema, :db_schemas, :
|
138
|
+
attr_accessor :default_schema, :db_schemas, :test_schema,
|
139
|
+
:routes_done, :is_oracle, :is_eager_loading, :auto_models, :initializer_loaded
|
139
140
|
|
140
141
|
def set_db_schema(params = nil)
|
141
142
|
# If Apartment::Tenant.current is not still the default (usually 'public') then an elevator has brought us into
|
@@ -148,6 +149,10 @@ module Brick
|
|
148
149
|
::Brick.db_schemas&.key?(schema)
|
149
150
|
Apartment::Tenant.switch!(schema)
|
150
151
|
schema
|
152
|
+
elsif ::Brick.test_schema
|
153
|
+
is_show_schema_list = true
|
154
|
+
Apartment::Tenant.switch!(::Brick.test_schema)
|
155
|
+
::Brick.test_schema
|
151
156
|
else
|
152
157
|
current_schema # Just return the current schema
|
153
158
|
end
|
@@ -601,7 +606,7 @@ In config/initializers/brick.rb appropriate entries would look something like:
|
|
601
606
|
def display_classes(prefix, rels, max_length)
|
602
607
|
rels.sort.each do |rel|
|
603
608
|
(::Brick.auto_models ||= []) << rel.first
|
604
|
-
puts "#{rel.first}#{' ' * (max_length - rel.first.length)} /#{prefix}#{rel.last}"
|
609
|
+
puts "#{rel.first}#{' ' * (max_length - rel.first.length)} /#{prefix}#{"#{rel[1]}/" if rel[1]}#{rel.last}"
|
605
610
|
end
|
606
611
|
puts "\n"
|
607
612
|
end
|
@@ -620,16 +625,21 @@ In config/initializers/brick.rb appropriate entries would look something like:
|
|
620
625
|
end
|
621
626
|
|
622
627
|
c_path_parts = ctrl_path.split('/')
|
628
|
+
found = nil
|
623
629
|
while c_path_parts.present?
|
624
630
|
possible_c_path = c_path_parts.join('.')
|
625
631
|
possible_c_path_singular = c_path_parts[0..-2] + [c_path_parts.last.singularize]
|
626
632
|
possible_sti = possible_c_path_singular.join('/').camelize
|
627
633
|
break if (
|
628
|
-
res_name = res_names[possible_c_path] ||
|
634
|
+
res_name = res_names[found = possible_c_path] ||
|
629
635
|
((klass = Brick.config.sti_namespace_prefixes.key?("::#{possible_sti}") && possible_sti.constantize) &&
|
630
636
|
(sti_type = possible_sti)) ||
|
631
637
|
# %%% Used to have the more flexible: (DidYouMean::SpellChecker.new(dictionary: res_names.keys).correct(possible_c_path)).first
|
632
|
-
res_names[possible_c_path] || res_names[possible_c_path_singular.join('.')]
|
638
|
+
res_names[found = possible_c_path] || res_names[found = possible_c_path_singular.join('.')] ||
|
639
|
+
((::Brick.config.table_name_prefixes.key?(tn_prefix = c_path_parts.first) ||
|
640
|
+
::Brick.config.table_name_prefixes.key?(tn_prefix = "#{c_path_parts.first}_")) &&
|
641
|
+
res_names[found = tn_prefix + c_path_parts.last]
|
642
|
+
)
|
633
643
|
) &&
|
634
644
|
(
|
635
645
|
klass ||
|
@@ -638,7 +648,7 @@ In config/initializers/brick.rb appropriate entries would look something like:
|
|
638
648
|
)
|
639
649
|
c_path_parts.shift
|
640
650
|
end
|
641
|
-
[klass, sti_type]
|
651
|
+
[klass, sti_type, found]
|
642
652
|
end
|
643
653
|
end
|
644
654
|
|
@@ -657,10 +667,14 @@ In config/initializers/brick.rb appropriate entries would look something like:
|
|
657
667
|
table_class_length = 38 # Length of "Classes that can be built from tables:"
|
658
668
|
view_class_length = 37 # Length of "Classes that can be built from views:"
|
659
669
|
|
660
|
-
|
661
|
-
if
|
662
|
-
|
663
|
-
|
670
|
+
brick_namespace_create = lambda do |path_names, res_name, options|
|
671
|
+
if path_names&.present?
|
672
|
+
if (path_name = path_names.pop).is_a?(Array)
|
673
|
+
module_name = path_name[1]
|
674
|
+
path_name = path_name.first
|
675
|
+
end
|
676
|
+
send(:scope, { module: module_name || path_name, path: path_name, as: path_name }) do
|
677
|
+
brick_namespace_create.call(path_names, res_name, options)
|
664
678
|
end
|
665
679
|
else
|
666
680
|
send(:resources, res_name.to_sym, **options)
|
@@ -676,13 +690,24 @@ In config/initializers/brick.rb appropriate entries would look something like:
|
|
676
690
|
end
|
677
691
|
versioned_views = {} # Track which views have already been done for each api_root
|
678
692
|
::Brick.relations.each do |k, v|
|
679
|
-
next if !(controller_name = v.fetch(:resource, nil)&.pluralize) || existing_controllers.key?(controller_name)
|
680
|
-
|
681
|
-
object_name = k.split('.').last # Take off any first schema part
|
682
693
|
if (schema_name = v.fetch(:schema, nil))
|
683
694
|
schema_prefix = "#{schema_name}."
|
684
695
|
end
|
685
696
|
|
697
|
+
next if !(resource_name = v.fetch(:resource, nil)) ||
|
698
|
+
existing_controllers.key?(controller_name = (
|
699
|
+
resource_name = "#{schema_prefix&.tr('.', '/')}#{resource_name}"
|
700
|
+
).pluralize)
|
701
|
+
|
702
|
+
object_name = k.split('.').last # Take off any first schema part
|
703
|
+
|
704
|
+
full_schema_prefix = if (aps = v.fetch(:auto_prefixed_schema, nil))
|
705
|
+
aps = aps[0..-2] if aps[-1] == '_'
|
706
|
+
(schema_prefix&.dup || +'') << "#{aps}."
|
707
|
+
else
|
708
|
+
schema_prefix
|
709
|
+
end
|
710
|
+
|
686
711
|
# Track routes being built
|
687
712
|
if (class_name = v.fetch(:class_name, nil))
|
688
713
|
if v.key?(:isView)
|
@@ -691,26 +716,20 @@ In config/initializers/brick.rb appropriate entries would look something like:
|
|
691
716
|
else
|
692
717
|
table_class_length = class_name.length if class_name.length > table_class_length
|
693
718
|
tables
|
694
|
-
end << [class_name,
|
719
|
+
end << [class_name, aps, resource_name]
|
695
720
|
end
|
696
721
|
|
697
722
|
options = {}
|
698
723
|
options[:only] = [:index, :show] if v.key?(:isView)
|
699
724
|
|
700
725
|
# First do the normal routes
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
-
end
|
709
|
-
else
|
710
|
-
brick_routes_create.call(schema_name, v[:resource], options)
|
711
|
-
sti_subclasses.fetch(class_name, nil)&.each do |sc| # Add any STI subclass routes for this relation
|
712
|
-
brick_routes_create.call(schema_name, sc.underscore.tr('/', '_').pluralize, options)
|
713
|
-
end
|
726
|
+
prefixes = []
|
727
|
+
prefixes << [aps, v[:class_name]&.split('::')[-2]&.underscore] if aps
|
728
|
+
prefixes << schema_name if schema_name
|
729
|
+
prefixes << path_prefix if path_prefix
|
730
|
+
brick_namespace_create.call(prefixes, v[:resource], options)
|
731
|
+
sti_subclasses.fetch(class_name, nil)&.each do |sc| # Add any STI subclass routes for this relation
|
732
|
+
brick_namespace_create.call(prefixes, sc.underscore.tr('/', '_').pluralize, options)
|
714
733
|
end
|
715
734
|
|
716
735
|
# Now the API routes if necessary
|
@@ -815,9 +834,8 @@ In config/initializers/brick.rb appropriate entries would look something like:
|
|
815
834
|
# view_ver_num = if (first_part = k.split('_').first) =~ /^v[\d_]+/
|
816
835
|
# first_part[1..-1].gsub('_', '.').to_i
|
817
836
|
# end
|
818
|
-
|
819
837
|
controller_name = if (last = view_relation.fetch(:resource, nil)&.pluralize)
|
820
|
-
"#{
|
838
|
+
"#{full_schema_prefix}#{last}"
|
821
839
|
else
|
822
840
|
found
|
823
841
|
end.tr('.', '/')
|
@@ -1484,12 +1502,12 @@ module ActiveRecord
|
|
1484
1502
|
# entry in your .select().
|
1485
1503
|
# More information: https://discuss.rubyonrails.org/t/includes-and-select-for-joined-data/81640
|
1486
1504
|
def apply_column_aliases(relation)
|
1487
|
-
if (
|
1505
|
+
if !(@join_root_alias = relation.select_values.empty?) &&
|
1506
|
+
relation.select_values.first.to_s == '_brick_eager_load'
|
1507
|
+
relation.select_values.shift
|
1488
1508
|
used_cols = {}
|
1489
1509
|
# Find and expand out all column names being used in select(...)
|
1490
|
-
new_select_values =
|
1491
|
-
next if col == '_brick_eager_load'
|
1492
|
-
|
1510
|
+
new_select_values = relation.select_values.map(&:to_s).each_with_object([]) do |col, s|
|
1493
1511
|
if col.include?(' ') # Some expression? (No chance for a simple column reference)
|
1494
1512
|
s << col # Just pass it through
|
1495
1513
|
else
|
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.111
|
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-
|
11
|
+
date: 2023-02-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|