brick 1.0.33 → 1.0.34
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 +88 -45
- data/lib/brick/frameworks/rails/engine.rb +21 -7
- data/lib/brick/version_number.rb +1 -1
- 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: 9d1e2f8b6ff7ca3fa7fcd129c33de3dfe6e674b6da154b9a64e094c65a3a152a
|
4
|
+
data.tar.gz: 30e39f62458a46854f56b2a6decbfe5ea42a4bb5325e81ed76f21400aae8e252
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 14c6bae09e34f53126e2003cbc7256c4b32f4a4219d42f1f7e94ca83211debf3704fa6c170cd6231d89e26eb168f282d1dea7eff7150ef1a013364aeb4eb65c3
|
7
|
+
data.tar.gz: 7f33aa5c89be2e8401f4cda0ea6cecb6e01639934a2df1e7b00bd88d065bf3cc9b748bebb1691d51c1b04114fba3b1739a7820c7614f4eb84d52494bd4cc769e
|
data/lib/brick/extensions.rb
CHANGED
@@ -163,6 +163,7 @@ module ActiveRecord
|
|
163
163
|
bracket_name.split('.').each do |part|
|
164
164
|
obj_name += ".#{part}"
|
165
165
|
this_obj = caches.fetch(obj_name) { caches[obj_name] = this_obj&.send(part.to_sym) }
|
166
|
+
break if this_obj.nil?
|
166
167
|
end
|
167
168
|
this_obj&.to_s || ''
|
168
169
|
end
|
@@ -308,6 +309,23 @@ module ActiveRecord
|
|
308
309
|
# , is_add_bts, is_add_hms
|
309
310
|
)
|
310
311
|
is_add_bts = is_add_hms = true
|
312
|
+
is_distinct = nil
|
313
|
+
wheres = {}
|
314
|
+
params.each do |k, v|
|
315
|
+
case (ks = k.split('.')).length
|
316
|
+
when 1
|
317
|
+
next unless klass._brick_get_fks.include?(k)
|
318
|
+
when 2
|
319
|
+
assoc_name = ks.first.to_sym
|
320
|
+
# Make sure it's a good association name and that the model has that column name
|
321
|
+
next unless klass.reflect_on_association(assoc_name)&.klass&.column_names&.any?(ks.last)
|
322
|
+
|
323
|
+
join_array[assoc_name] = nil # Store this relation name in our special collection for .joins()
|
324
|
+
is_distinct = true
|
325
|
+
distinct!
|
326
|
+
end
|
327
|
+
wheres[k] = v.split(',')
|
328
|
+
end
|
311
329
|
|
312
330
|
# %%% Skip the metadata columns
|
313
331
|
if selects&.empty? # Default to all columns
|
@@ -316,7 +334,9 @@ module ActiveRecord
|
|
316
334
|
if (col_name = col.name) == 'class'
|
317
335
|
col_alias = ' AS _class'
|
318
336
|
end
|
319
|
-
|
337
|
+
# Postgres can not use DISTINCT with any columns that are XML, so for any of those just convert to text
|
338
|
+
cast_as_text = '::text' if is_distinct && Brick.relations[klass.table_name]&.[](:cols)&.[](col.name)&.first&.start_with?('xml')
|
339
|
+
selects << "\"#{tbl_no_schema}\".\"#{col_name}\"#{cast_as_text}#{col_alias}"
|
320
340
|
end
|
321
341
|
end
|
322
342
|
|
@@ -342,22 +362,6 @@ module ActiveRecord
|
|
342
362
|
end
|
343
363
|
end
|
344
364
|
|
345
|
-
wheres = {}
|
346
|
-
params.each do |k, v|
|
347
|
-
case (ks = k.split('.')).length
|
348
|
-
when 1
|
349
|
-
next unless klass._brick_get_fks.include?(k)
|
350
|
-
when 2
|
351
|
-
assoc_name = ks.first.to_sym
|
352
|
-
# Make sure it's a good association name and that the model has that column name
|
353
|
-
next unless klass.reflect_on_association(assoc_name)&.klass&.column_names&.any?(ks.last)
|
354
|
-
|
355
|
-
join_array[assoc_name] = nil # Store this relation name in our special collection for .joins()
|
356
|
-
distinct!
|
357
|
-
end
|
358
|
-
wheres[k] = v.split(',')
|
359
|
-
end
|
360
|
-
|
361
365
|
if join_array.present?
|
362
366
|
left_outer_joins!(join_array)
|
363
367
|
# Without working from a duplicate, touching the AREL ast tree sets the @arel instance variable, which causes the relation to be immutable.
|
@@ -375,7 +379,9 @@ module ActiveRecord
|
|
375
379
|
v1.map { |x| [translations[x[0..-2].map(&:to_s).join('.')], x.last] }.each_with_index do |sel_col, idx|
|
376
380
|
field_tbl_name = (field_tbl_names[v.first][sel_col.first] ||= shift_or_first(chains[sel_col.first])).split('.').last
|
377
381
|
|
378
|
-
|
382
|
+
# Postgres can not use DISTINCT with any columns that are XML, so for any of those just convert to text
|
383
|
+
is_xml = is_distinct && Brick.relations[sel_col.first.table_name]&.[](:cols)&.[](sel_col.last)&.first&.start_with?('xml')
|
384
|
+
selects << "\"#{field_tbl_name}\".\"#{sel_col.last}\"#{'::text' if is_xml} AS \"#{(col_alias = "_brfk_#{v.first}__#{sel_col.last}")}\""
|
379
385
|
v1[idx] << col_alias
|
380
386
|
end
|
381
387
|
|
@@ -571,11 +577,13 @@ Module.class_exec do
|
|
571
577
|
[built_module, "module #{schema_name}; end\n"]
|
572
578
|
# # %%% Perhaps an option to use the first module just as schema, and additional modules as namespace with a table name prefix applied
|
573
579
|
elsif ::Brick.enable_models?
|
580
|
+
# Custom inheritable Brick base model?
|
581
|
+
class_name = (inheritable_name = class_name)[5..-1] if class_name.start_with?('Brick')
|
574
582
|
# See if a file is there in the same way that ActiveSupport::Dependencies#load_missing_constant
|
575
583
|
# checks for it in ~/.rvm/gems/ruby-2.7.5/gems/activesupport-5.2.6.2/lib/active_support/dependencies.rb
|
576
584
|
|
577
|
-
if
|
578
|
-
|
585
|
+
if (base_model = ::Brick.config.sti_namespace_prefixes&.fetch("::#{name}::", nil)&.constantize) || # Are we part of an auto-STI namespace? ...
|
586
|
+
self != Object # ... or otherwise already in some namespace?
|
579
587
|
schema_name = [(singular_schema_name = name.underscore),
|
580
588
|
(schema_name = singular_schema_name.pluralize),
|
581
589
|
name,
|
@@ -588,7 +596,7 @@ Module.class_exec do
|
|
588
596
|
if base_model
|
589
597
|
schema_name = name.underscore # For the auto-STI namespace models
|
590
598
|
table_name = base_model.table_name
|
591
|
-
Object.send(:build_model, self, model_name, singular_table_name, table_name, relations, table_name)
|
599
|
+
Object.send(:build_model, self, inheritable_name, model_name, singular_table_name, table_name, relations, table_name)
|
592
600
|
else
|
593
601
|
# Adjust for STI if we know of a base model for the requested model name
|
594
602
|
# %%% Does not yet work with namespaced model names. Perhaps prefix with plural_class_name when doing the lookups here.
|
@@ -603,7 +611,7 @@ Module.class_exec do
|
|
603
611
|
end
|
604
612
|
# Maybe, just maybe there's a database table that will satisfy this need
|
605
613
|
if (matching = [table_name, singular_table_name, plural_class_name, model_name].find { |m| relations.key?(schema_name ? "#{schema_name}.#{m}" : m) })
|
606
|
-
Object.send(:build_model, schema_name, model_name, singular_table_name, table_name, relations, matching)
|
614
|
+
Object.send(:build_model, schema_name, inheritable_name, model_name, singular_table_name, table_name, relations, matching)
|
607
615
|
end
|
608
616
|
end
|
609
617
|
end
|
@@ -631,12 +639,12 @@ class Object
|
|
631
639
|
|
632
640
|
private
|
633
641
|
|
634
|
-
def build_model(schema_name, model_name, singular_table_name, table_name, relations, matching)
|
642
|
+
def build_model(schema_name, inheritable_name, model_name, singular_table_name, table_name, relations, matching)
|
635
643
|
full_name = if (::Brick.config.schema_behavior[:multitenant] && Object.const_defined?('Apartment') && schema_name == Apartment.default_schema)
|
636
644
|
relation = relations["#{schema_name}.#{matching}"]
|
637
|
-
model_name
|
645
|
+
inheritable_name || model_name
|
638
646
|
elsif schema_name.blank?
|
639
|
-
model_name
|
647
|
+
inheritable_name || model_name
|
640
648
|
else # Prefix the schema to the table name + prefix the schema namespace to the class name
|
641
649
|
schema_module = if schema_name.instance_of?(Module) # from an auto-STI namespace?
|
642
650
|
schema_name
|
@@ -644,7 +652,7 @@ class Object
|
|
644
652
|
matching = "#{schema_name}.#{matching}"
|
645
653
|
(Brick.db_schemas[schema_name] ||= self.const_get(schema_name.singularize.camelize))
|
646
654
|
end
|
647
|
-
"#{schema_module&.name}::#{model_name}"
|
655
|
+
"#{schema_module&.name}::#{inheritable_name || model_name}"
|
648
656
|
end
|
649
657
|
|
650
658
|
return if ((is_view = (relation ||= relations[matching]).key?(:isView)) && ::Brick.config.skip_database_views) ||
|
@@ -653,12 +661,14 @@ class Object
|
|
653
661
|
# Are they trying to use a pluralised class name such as "Employees" instead of "Employee"?
|
654
662
|
if table_name == singular_table_name && !ActiveSupport::Inflector.inflections.uncountable.include?(table_name)
|
655
663
|
unless ::Brick.config.sti_namespace_prefixes&.key?("::#{singular_table_name.camelize}::")
|
656
|
-
puts "Warning: Class name for a model that references table \"#{matching
|
664
|
+
puts "Warning: Class name for a model that references table \"#{matching
|
665
|
+
}\" should be \"#{ActiveSupport::Inflector.singularize(inheritable_name || model_name)}\"."
|
657
666
|
end
|
658
667
|
return
|
659
668
|
end
|
660
669
|
|
661
|
-
|
670
|
+
full_model_name = full_name.split('::').tap { |fn| fn[-1] = model_name }.join('::')
|
671
|
+
if (base_model = ::Brick.sti_models[full_model_name]&.fetch(:base, nil) || ::Brick.existing_stis[full_model_name]&.constantize)
|
662
672
|
is_sti = true
|
663
673
|
else
|
664
674
|
base_model = ::Brick.config.models_inherit_from || ActiveRecord::Base
|
@@ -666,9 +676,21 @@ class Object
|
|
666
676
|
hmts = nil
|
667
677
|
code = +"class #{full_name} < #{base_model.name}\n"
|
668
678
|
built_model = Class.new(base_model) do |new_model_class|
|
669
|
-
(schema_module || Object).const_set(model_name.to_sym, new_model_class)
|
679
|
+
(schema_module || Object).const_set((inheritable_name || model_name).to_sym, new_model_class)
|
680
|
+
if inheritable_name
|
681
|
+
new_model_class.define_singleton_method :inherited do |subclass|
|
682
|
+
super(subclass)
|
683
|
+
if subclass.name == model_name
|
684
|
+
puts "#{full_model_name} properly extends from #{full_name}"
|
685
|
+
else
|
686
|
+
puts "should be \"class #{model_name} < #{inheritable_name}\"\n (not \"#{subclass.name} < #{inheritable_name}\")"
|
687
|
+
end
|
688
|
+
end
|
689
|
+
self.abstract_class = true
|
690
|
+
code << " self.abstract_class = true\n"
|
691
|
+
end
|
670
692
|
# Accommodate singular or camel-cased table names such as "order_detail" or "OrderDetails"
|
671
|
-
code << " self.table_name = '#{self.table_name = matching}'\n"
|
693
|
+
code << " self.table_name = '#{self.table_name = matching}'\n" if inheritable_name || table_name != matching
|
672
694
|
|
673
695
|
# Override models backed by a view so they return true for #is_view?
|
674
696
|
# (Dynamically-created controllers and view templates for such models will then act in a read-only way)
|
@@ -880,19 +902,19 @@ class Object
|
|
880
902
|
{ 'url': 'https://{defaultHost}', 'variables': { 'defaultHost': { 'default': 'www.example.com' } } }
|
881
903
|
]
|
882
904
|
}
|
883
|
-
json['paths'] = relations.
|
884
|
-
# next if v.last[:is_view]
|
885
|
-
|
905
|
+
json['paths'] = relations.inject({}) do |s, v|
|
886
906
|
s["/api/v1/#{v.first}"] = {
|
887
907
|
'get': {
|
888
|
-
'summary':
|
908
|
+
'summary': "list #{v.first}",
|
889
909
|
'parameters': v.last[:cols].map { |k, v| { 'name' => k, 'schema': { 'type': v.first } } },
|
890
910
|
'responses': { '200': { 'description': 'successful' } }
|
891
911
|
}
|
892
912
|
}
|
913
|
+
# next if v.last[:isView]
|
914
|
+
|
893
915
|
s["/api/v1/#{v.first}/{id}"] = {
|
894
916
|
'patch': {
|
895
|
-
'summary':
|
917
|
+
'summary': "update a #{v.first.singularize}",
|
896
918
|
'parameters': v.last[:cols].reject { |k, v| Brick.config.metadata_columns.include?(k) }.map do |k, v|
|
897
919
|
{ 'name' => k, 'schema': { 'type': v.first } }
|
898
920
|
end,
|
@@ -918,6 +940,7 @@ class Object
|
|
918
940
|
# }
|
919
941
|
# ],
|
920
942
|
}
|
943
|
+
s
|
921
944
|
end
|
922
945
|
# binding.pry
|
923
946
|
render inline: json.to_json, content_type: request.format
|
@@ -1090,12 +1113,14 @@ module ActiveRecord::ConnectionHandling
|
|
1090
1113
|
when 'Mysql2'
|
1091
1114
|
::Brick.default_schema = schema = ActiveRecord::Base.connection.current_database
|
1092
1115
|
when 'SQLite'
|
1116
|
+
# %%% Retrieve internal ActiveRecord table names like this:
|
1117
|
+
# ActiveRecord::Base.internal_metadata_table_name, ActiveRecord::Base.schema_migrations_table_name
|
1093
1118
|
sql = "SELECT m.name AS relation_name, UPPER(m.type) AS table_type,
|
1094
1119
|
p.name AS column_name, p.type AS data_type,
|
1095
1120
|
CASE p.pk WHEN 1 THEN 'PRIMARY KEY' END AS const
|
1096
1121
|
FROM sqlite_master AS m
|
1097
1122
|
INNER JOIN pragma_table_info(m.name) AS p
|
1098
|
-
WHERE m.name NOT IN (
|
1123
|
+
WHERE m.name NOT IN (?, ?)
|
1099
1124
|
ORDER BY m.name, p.cid"
|
1100
1125
|
else
|
1101
1126
|
puts "Unfamiliar with connection adapter #{ActiveRecord::Base.connection.adapter_name}"
|
@@ -1123,6 +1148,9 @@ module ActiveRecord::ConnectionHandling
|
|
1123
1148
|
end
|
1124
1149
|
end
|
1125
1150
|
|
1151
|
+
# %%% Retrieve internal ActiveRecord table names like this:
|
1152
|
+
# ActiveRecord::Base.internal_metadata_table_name, ActiveRecord::Base.schema_migrations_table_name
|
1153
|
+
# For if it's not SQLite -- so this is the Postgres and MySQL version
|
1126
1154
|
sql ||= "SELECT t.table_schema AS schema, t.table_name AS relation_name, t.table_type,
|
1127
1155
|
c.column_name, c.data_type,
|
1128
1156
|
COALESCE(c.character_maximum_length, c.numeric_precision) AS max_length,
|
@@ -1144,13 +1172,13 @@ module ActiveRecord::ConnectionHandling
|
|
1144
1172
|
WHERE t.table_schema NOT IN ('information_schema', 'pg_catalog')#{"
|
1145
1173
|
AND t.table_schema = COALESCE(current_setting('SEARCH_PATH'), 'public')" if schema }
|
1146
1174
|
-- AND t.table_type IN ('VIEW') -- 'BASE TABLE', 'FOREIGN TABLE'
|
1147
|
-
AND t.table_name NOT IN ('pg_stat_statements',
|
1175
|
+
AND t.table_name NOT IN ('pg_stat_statements', ?, ?)
|
1148
1176
|
ORDER BY 1, t.table_type DESC, c.ordinal_position"
|
1149
1177
|
measures = []
|
1150
1178
|
case ActiveRecord::Base.connection.adapter_name
|
1151
1179
|
when 'PostgreSQL', 'SQLite' # These bring back a hash for each row because the query uses column aliases
|
1152
1180
|
# schema ||= 'public' if ActiveRecord::Base.connection.adapter_name == 'PostgreSQL'
|
1153
|
-
ActiveRecord::Base.execute_sql(sql).each do |r|
|
1181
|
+
ActiveRecord::Base.execute_sql(sql, ActiveRecord::Base.internal_metadata_table_name, ActiveRecord::Base.schema_migrations_table_name).each do |r|
|
1154
1182
|
# If Apartment gem lists the table as being associated with a non-tenanted model then use whatever it thinks
|
1155
1183
|
# is the default schema, usually 'public'.
|
1156
1184
|
schema_name = if ::Brick.config.schema_behavior[:multitenant]
|
@@ -1259,11 +1287,25 @@ module ActiveRecord::ConnectionHandling
|
|
1259
1287
|
end
|
1260
1288
|
end
|
1261
1289
|
|
1262
|
-
|
1263
|
-
|
1264
|
-
|
1290
|
+
apartment = Object.const_defined?('Apartment') && Apartment
|
1291
|
+
tables = []
|
1292
|
+
views = []
|
1293
|
+
relations.each do |k, v|
|
1294
|
+
name_parts = k.split('.')
|
1295
|
+
if v.key?(:isView)
|
1296
|
+
views
|
1297
|
+
else
|
1298
|
+
name_parts.shift if apartment && name_parts.length > 1 && name_parts.first == Apartment.default_schema
|
1299
|
+
tables
|
1300
|
+
end << name_parts.map { |x| x.singularize.camelize }.join('::')
|
1301
|
+
end
|
1302
|
+
unless tables.empty?
|
1303
|
+
puts "\nClasses that can be built from tables:"
|
1304
|
+
tables.sort.each { |x| puts x }
|
1305
|
+
end
|
1306
|
+
unless views.empty?
|
1265
1307
|
puts "\nClasses that can be built from views:"
|
1266
|
-
views.
|
1308
|
+
views.sort.each { |x| puts x }
|
1267
1309
|
end
|
1268
1310
|
|
1269
1311
|
::Brick.load_additional_references if initializer_loaded
|
@@ -1306,7 +1348,8 @@ module Brick
|
|
1306
1348
|
end
|
1307
1349
|
# %%% Temporary schema patch
|
1308
1350
|
for_tbl = fk[1]
|
1309
|
-
|
1351
|
+
apartment = Object.const_defined?('Apartment') && Apartment
|
1352
|
+
fk[0] = Apartment.default_schema if apartment && apartment.excluded_models.include?(for_tbl.singularize.camelize)
|
1310
1353
|
fk[1] = "#{fk[0]}.#{fk[1]}" if fk[0] # && fk[0] != ::Brick.default_schema
|
1311
1354
|
bts = (relation = relations.fetch(fk[1], nil))&.fetch(:fks) { relation[:fks] = {} }
|
1312
1355
|
|
@@ -1321,7 +1364,7 @@ module Brick
|
|
1321
1364
|
is_schema = if ::Brick.config.schema_behavior[:multitenant]
|
1322
1365
|
# If Apartment gem lists the primary table as being associated with a non-tenanted model
|
1323
1366
|
# then use 'public' schema for the primary table
|
1324
|
-
if
|
1367
|
+
if apartment&.excluded_models.include?(fk[4].singularize.camelize)
|
1325
1368
|
fk[3] = Apartment.default_schema
|
1326
1369
|
true
|
1327
1370
|
end
|
@@ -1398,7 +1441,7 @@ module Brick
|
|
1398
1441
|
assoc_hm[:alternate_name] = "#{assoc_hm[:alternate_name]}_#{bt_assoc_name}" unless assoc_hm[:alternate_name] == bt_assoc_name
|
1399
1442
|
assoc_hm[:inverse] = assoc_bt
|
1400
1443
|
else
|
1401
|
-
inv_tbl = if ::Brick.config.schema_behavior[:multitenant] &&
|
1444
|
+
inv_tbl = if ::Brick.config.schema_behavior[:multitenant] && apartment && fk[0] == Apartment.default_schema
|
1402
1445
|
for_tbl
|
1403
1446
|
else
|
1404
1447
|
fk[1]
|
@@ -124,8 +124,15 @@ module Brick
|
|
124
124
|
schema_options = ::Brick.db_schemas.keys.each_with_object(+'') { |v, s| s << "<option value=\"#{v}\">#{v}</option>" }.html_safe
|
125
125
|
# %%% If we are not auto-creating controllers (or routes) then omit by default, and if enabled anyway, such as in a development
|
126
126
|
# environment or whatever, then get either the controllers or routes list instead
|
127
|
-
|
128
|
-
|
127
|
+
apartment_default_schema = ::Brick.config.schema_behavior[:multitenant] && Object.const_defined?('Apartment') && Apartment.default_schema
|
128
|
+
table_options = (::Brick.relations.keys - ::Brick.config.exclude_tables).map do |tbl|
|
129
|
+
if (tbl_parts = tbl.split('.')).first == apartment_default_schema
|
130
|
+
tbl = tbl_parts.last
|
131
|
+
end
|
132
|
+
tbl
|
133
|
+
end.sort.each_with_object(+'') do |v, s|
|
134
|
+
s << "<option value=\"#{v.underscore.gsub('.', '/').pluralize}\">#{v}</option>"
|
135
|
+
end.html_safe
|
129
136
|
css = +"<style>
|
130
137
|
#dropper {
|
131
138
|
background-color: #eee;
|
@@ -238,9 +245,10 @@ end %>"
|
|
238
245
|
poly_cols = #{poly_cols.inspect} %>"
|
239
246
|
end
|
240
247
|
|
241
|
-
# %%% When doing schema select, if
|
248
|
+
# %%% When doing schema select, if we're on a new page go to index
|
242
249
|
script = "<script>
|
243
250
|
var schemaSelect = document.getElementById(\"schema\");
|
251
|
+
var tblSelect = document.getElementById(\"tbl\");
|
244
252
|
var brickSchema;
|
245
253
|
if (schemaSelect) {
|
246
254
|
brickSchema = changeout(location.href, \"_brick_schema\");
|
@@ -250,7 +258,8 @@ if (schemaSelect) {
|
|
250
258
|
schemaSelect.value = brickSchema || \"public\";
|
251
259
|
schemaSelect.focus();
|
252
260
|
schemaSelect.addEventListener(\"change\", function () {
|
253
|
-
|
261
|
+
// If there's an ID then remove it (trim after selected table)
|
262
|
+
location.href = changeout(location.href, \"_brick_schema\", this.value, tblSelect.value);
|
254
263
|
});
|
255
264
|
}
|
256
265
|
[... document.getElementsByTagName(\"FORM\")].forEach(function (form) {
|
@@ -265,7 +274,6 @@ if (schemaSelect) {
|
|
265
274
|
});
|
266
275
|
});
|
267
276
|
|
268
|
-
var tblSelect = document.getElementById(\"tbl\");
|
269
277
|
if (tblSelect) {
|
270
278
|
tblSelect.value = changeout(location.href)[0];
|
271
279
|
if (tblSelect.selectedIndex < 0) tblSelect.value = changeout(location.href)[1];
|
@@ -277,7 +285,7 @@ if (tblSelect) {
|
|
277
285
|
});
|
278
286
|
}
|
279
287
|
|
280
|
-
function changeout(href, param, value) {
|
288
|
+
function changeout(href, param, value, trimAfter) {
|
281
289
|
var hrefParts = href.split(\"?\");
|
282
290
|
if (param === undefined || param === null) {
|
283
291
|
hrefParts = hrefParts[0].split(\"://\");
|
@@ -288,6 +296,11 @@ function changeout(href, param, value) {
|
|
288
296
|
else
|
289
297
|
return hrefParts[0] + \"://\" + pathParts[0] + \"/\" + value;
|
290
298
|
}
|
299
|
+
if (trimAfter) {
|
300
|
+
var pathParts = hrefParts[0].split(\"/\");
|
301
|
+
while (pathParts.lastIndexOf(trimAfter) != pathParts.length - 1) pathParts.pop();
|
302
|
+
hrefParts[0] = pathParts.join(\"/\");
|
303
|
+
}
|
291
304
|
var params = hrefParts.length > 1 ? hrefParts[1].split(\"&\") : [];
|
292
305
|
params = params.reduce(function (s, v) { var parts = v.split(\"=\"); s[parts[0]] = parts[1]; return s; }, {});
|
293
306
|
if (value === undefined) return params[param];
|
@@ -566,7 +579,7 @@ function changeout(href, param, value) {
|
|
566
579
|
s << "<table id=\"#{hm_name}\">
|
567
580
|
<tr><th>#{hm[3]}</th></tr>
|
568
581
|
<% collection = @#{obj_name}.#{hm_name}
|
569
|
-
collection = collection.is_a?(ActiveRecord::Associations::CollectionProxy) ? collection.order(#{pk.inspect}) : [collection]
|
582
|
+
collection = collection.is_a?(ActiveRecord::Associations::CollectionProxy) ? collection.order(#{pk.inspect}) : [collection].compact
|
570
583
|
if collection.empty? %>
|
571
584
|
<tr><td>(none)</td></tr>
|
572
585
|
<% else %>
|
@@ -600,6 +613,7 @@ function changeout(href, param, value) {
|
|
600
613
|
|
601
614
|
# Just in case it hadn't been done previously when we tried to load the brick initialiser,
|
602
615
|
# go make sure we've loaded additional references (virtual foreign keys and polymorphic associations).
|
616
|
+
# (This should only happen if for whatever reason the initializer file was not exactly config/initializers/brick.rb.)
|
603
617
|
::Brick.load_additional_references
|
604
618
|
end
|
605
619
|
end
|
data/lib/brick/version_number.rb
CHANGED
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.34
|
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-06-
|
11
|
+
date: 2022-06-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|