brick 1.0.127 → 1.0.129
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 +120 -85
- data/lib/brick/frameworks/rails/engine.rb +77 -43
- data/lib/brick/frameworks/rails/form_tags.rb +8 -1
- 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: 3b46bf80d393c0d6e4ffea3e8bfc1fbc03dc667902077efc9a887c8ab046a817
|
4
|
+
data.tar.gz: 927828e46dfd9ae6b7c14aced0f814bbc1d876e5af14aa872a13d2c13af85083
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 49073fb48479c8df6805a35632ef321efa3144556feb1e2da701044ce110aa6cfcb8ced12186408929b8c3d6280ca6e393e886ba54eea87f0a622a58f9216e8e
|
7
|
+
data.tar.gz: eaccf857c54a108c764e786b5e8abd0f54ff5abbcadec558138dc947a5d7e3015fc1a5510a311301947cee815d086018e535a15958357abd3463ab59ee375908
|
data/lib/brick/extensions.rb
CHANGED
@@ -108,16 +108,16 @@ module ActiveRecord
|
|
108
108
|
dsl
|
109
109
|
end
|
110
110
|
|
111
|
-
def self.brick_parse_dsl(
|
112
|
-
unless
|
113
|
-
|
114
|
-
|
111
|
+
def self.brick_parse_dsl(join_array = nil, prefix = [], translations = {}, is_polymorphic = false, dsl = nil, emit_dsl = false)
|
112
|
+
unless join_array.is_a?(::Brick::JoinArray)
|
113
|
+
join_array = ::Brick::JoinArray.new.tap { |ary| ary.replace([join_array]) } if join_array.is_a?(::Brick::JoinHash)
|
114
|
+
join_array = ::Brick::JoinArray.new unless join_array.nil? || join_array.is_a?(Array)
|
115
115
|
end
|
116
116
|
prefix = [prefix] unless prefix.is_a?(Array)
|
117
117
|
members = []
|
118
118
|
unless dsl || (dsl = ::Brick.config.model_descrips[name] || brick_get_dsl)
|
119
119
|
# With no DSL available, still put this prefix into the JoinArray so we can get primary key (ID) info from this table
|
120
|
-
x = prefix.each_with_object(
|
120
|
+
x = prefix.each_with_object(join_array) { |v, s| s[v.to_sym] }
|
121
121
|
x[prefix.last] = nil unless prefix.empty? # Using []= will "hydrate" any missing part(s) in our whole series
|
122
122
|
return members
|
123
123
|
end
|
@@ -141,7 +141,7 @@ module ActiveRecord
|
|
141
141
|
if first_parts
|
142
142
|
if (parts = prefix + first_parts + [parts[-1]]).length > 1 && klass
|
143
143
|
unless is_polymorphic
|
144
|
-
s =
|
144
|
+
s = join_array
|
145
145
|
parts[0..-3].each { |v| s = s[v.to_sym] }
|
146
146
|
s[parts[-2]] = nil # unless parts[-2].empty? # Using []= will "hydrate" any missing part(s) in our whole series
|
147
147
|
end
|
@@ -153,7 +153,7 @@ module ActiveRecord
|
|
153
153
|
prefix << parts.shift until parts.empty?
|
154
154
|
end
|
155
155
|
# Expand this entry which refers to an association name
|
156
|
-
members2, dsl2a = klass.brick_parse_dsl(
|
156
|
+
members2, dsl2a = klass.brick_parse_dsl(join_array, prefix + [possible_dsl], translations, is_polymorphic, nil, true)
|
157
157
|
members += members2
|
158
158
|
dsl2 << dsl2a
|
159
159
|
dsl3 << dsl2a
|
@@ -434,7 +434,9 @@ module ActiveRecord
|
|
434
434
|
@brick_links ||= { '' => table_name }
|
435
435
|
end
|
436
436
|
|
437
|
-
def brick_select(params, selects = [], order_by = nil, translations = {},
|
437
|
+
def brick_select(params, selects = [], order_by = nil, translations = {},
|
438
|
+
join_array = ::Brick::JoinArray.new,
|
439
|
+
cust_col_override = nil)
|
438
440
|
is_add_bts = is_add_hms = true
|
439
441
|
|
440
442
|
# Build out cust_cols, bt_descrip and hm_counts now so that they are available on the
|
@@ -467,7 +469,7 @@ module ActiveRecord
|
|
467
469
|
is_distinct = true
|
468
470
|
distinct!
|
469
471
|
end
|
470
|
-
wheres[k] = v.split(',')
|
472
|
+
wheres[k] = v.is_a?(String) ? v.split(',') : v
|
471
473
|
end
|
472
474
|
|
473
475
|
# %%% Skip the metadata columns
|
@@ -506,84 +508,90 @@ module ActiveRecord
|
|
506
508
|
end
|
507
509
|
end
|
508
510
|
|
509
|
-
if join_array.present?
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
511
|
+
left_outer_joins!(join_array) if join_array.present?
|
512
|
+
|
513
|
+
# If it's a CollectionProxy (which inherits from Relation) then need to dig out the
|
514
|
+
# core Relation object which is found in the association scope.
|
515
|
+
rel_dupe = (is_a?(ActiveRecord::Associations::CollectionProxy) ? scope : self).dup
|
516
|
+
|
517
|
+
# Touching AREL AST walks the JoinDependency tree, and in that process uses our
|
518
|
+
# "brick_links" patch to find how every AR chain of association names relates to exact
|
519
|
+
# table correlation names chosen by AREL. We use a duplicate relation object for this
|
520
|
+
# because an important side-effect of referencing the AST is that the @arel instance
|
521
|
+
# variable gets set, and this is a signal to ActiveRecord that a relation has now
|
522
|
+
# become immutable. (We aren't quite ready for our "real deal" relation object to be
|
523
|
+
# set in stone ... still need to add .select(), and possibly .where() and .order()
|
524
|
+
# things ... also if there are any HM counts then an OUTER JOIN for each of them out
|
525
|
+
# to a derived table to do that counting. All of these things need to know proper
|
526
|
+
# table correlation names, which will now become available in brick_links on the
|
527
|
+
# rel_dupe object.)
|
528
|
+
rel_dupe.arel.ast
|
529
|
+
|
530
|
+
core_selects = selects.dup
|
531
|
+
id_for_tables = Hash.new { |h, k| h[k] = [] }
|
532
|
+
field_tbl_names = Hash.new { |h, k| h[k] = {} }
|
533
|
+
used_col_aliases = {} # Used to make sure there is not a name clash
|
534
|
+
|
535
|
+
# CUSTOM COLUMNS
|
536
|
+
# ==============
|
537
|
+
(cust_col_override || klass._br_cust_cols).each do |k, cc|
|
538
|
+
if rel_dupe.respond_to?(k) # Name already taken?
|
539
|
+
# %%% Use ensure_unique here in this kind of fashion:
|
540
|
+
# cnstr_name = ensure_unique(+"(brick) #{for_tbl}_#{pri_tbl}", bts, hms)
|
541
|
+
# binding.pry
|
542
|
+
next
|
543
|
+
end
|
538
544
|
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
end
|
561
|
-
end
|
562
|
-
used_col_aliases[col_alias] = nil
|
563
|
-
# Set up custom column links by preparing key_klass and key_alias
|
564
|
-
# (If there are multiple different tables referenced in the DSL, we end up creating a link to the last one)
|
565
|
-
if cc[2] && (dest_pk = dest_klass.primary_key)
|
566
|
-
key_klass = dest_klass
|
567
|
-
key_tbl_name = tbl_name
|
568
|
-
cc_part_idx = cc_part.length - 1
|
569
|
-
while cc_part_idx > 0 &&
|
570
|
-
(key_alias = "br_cc_#{k}__#{(cc_part[cc_part_idx..-2] + [dest_pk]).map(&:to_s).join('__')}") &&
|
571
|
-
key_alias != col_alias && # We break out if this key alias does exactly match the col_alias
|
572
|
-
used_col_aliases.key?(key_alias)
|
573
|
-
cc_part_idx -= 1
|
574
|
-
end
|
545
|
+
key_klass = nil
|
546
|
+
key_tbl_name = nil
|
547
|
+
dest_pk = nil
|
548
|
+
key_alias = nil
|
549
|
+
cc.first.each do |cc_part|
|
550
|
+
dest_klass = cc_part[0..-2].inject(klass) do |kl, cc_part_term|
|
551
|
+
# %%% Clear column info properly so we can do multiple subsequent requests
|
552
|
+
# binding.pry unless kl.reflect_on_association(cc_part_term)
|
553
|
+
kl.reflect_on_association(cc_part_term)&.klass || klass
|
554
|
+
end
|
555
|
+
tbl_name = rel_dupe.brick_links[cc_part[0..-2].map(&:to_s).join('.')]
|
556
|
+
# Deal with the conflict if there are two parts in the custom column named the same,
|
557
|
+
# "category.name" and "product.name" for instance will end up with aliases of "name"
|
558
|
+
# and "product__name".
|
559
|
+
if (cc_part_idx = cc_part.length - 1).zero?
|
560
|
+
col_alias = "br_cc_#{k}__#{table_name.tr('.', '_')}_#{cc_part.first}"
|
561
|
+
else
|
562
|
+
while cc_part_idx > 0 &&
|
563
|
+
(col_alias = "br_cc_#{k}__#{cc_part[cc_part_idx..-1].map(&:to_s).join('__').tr('.', '_')}") &&
|
564
|
+
used_col_aliases.key?(col_alias)
|
565
|
+
cc_part_idx -= 1
|
575
566
|
end
|
576
|
-
selects << "#{tbl_name}.#{cc_part.last} AS #{col_alias}"
|
577
|
-
cc_part << col_alias
|
578
567
|
end
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
568
|
+
used_col_aliases[col_alias] = nil
|
569
|
+
# Set up custom column links by preparing key_klass and key_alias
|
570
|
+
# (If there are multiple different tables referenced in the DSL, we end up creating a link to the last one)
|
571
|
+
if cc[2] && (dest_pk = dest_klass.primary_key)
|
572
|
+
key_klass = dest_klass
|
573
|
+
key_tbl_name = tbl_name
|
574
|
+
cc_part_idx = cc_part.length - 1
|
575
|
+
while cc_part_idx > 0 &&
|
576
|
+
(key_alias = "br_cc_#{k}__#{(cc_part[cc_part_idx..-2] + [dest_pk]).map(&:to_s).join('__')}") &&
|
577
|
+
key_alias != col_alias && # We break out if this key alias does exactly match the col_alias
|
578
|
+
used_col_aliases.key?(key_alias)
|
579
|
+
cc_part_idx -= 1
|
580
|
+
end
|
583
581
|
end
|
584
|
-
|
582
|
+
selects << "#{tbl_name}.#{cc_part.last} AS #{col_alias}"
|
583
|
+
cc_part << col_alias
|
585
584
|
end
|
585
|
+
# Add a key column unless we've already got it
|
586
|
+
if key_alias && !used_col_aliases.key?(key_alias)
|
587
|
+
selects << "#{key_tbl_name}.#{dest_pk} AS #{key_alias}"
|
588
|
+
used_col_aliases[key_alias] = nil
|
589
|
+
end
|
590
|
+
cc[2] = key_alias ? [key_klass, key_alias] : nil
|
591
|
+
end
|
586
592
|
|
593
|
+
# LEFT OUTER JOINs
|
594
|
+
unless cust_col_override
|
587
595
|
klass._br_bt_descrip.each do |v|
|
588
596
|
v.last.each do |k1, v1| # k1 is class, v1 is array of columns to snag
|
589
597
|
next unless (tbl_name = rel_dupe.brick_links[v.first.to_s]&.split('.')&.last)
|
@@ -644,6 +652,7 @@ module ActiveRecord
|
|
644
652
|
_assoc_names[assoc_name] = [table_alias, klass]
|
645
653
|
end
|
646
654
|
end
|
655
|
+
|
647
656
|
# Add derived table JOIN for the has_many counts
|
648
657
|
nix = []
|
649
658
|
klass._br_hm_counts.each do |k, hm|
|
@@ -781,7 +790,7 @@ module ActiveRecord
|
|
781
790
|
JOIN (SELECT #{hm_selects.map { |s| "#{'br_t0.' if from_clause}#{s}" }.join(', ')}, COUNT(#{'DISTINCT ' if hm.options[:through]}#{count_column
|
782
791
|
}) AS c_t_ FROM #{from_clause || hm_table_name} GROUP BY #{group_bys.join(', ')}) #{tbl_alias}"
|
783
792
|
self.joins_values |= ["#{join_clause} ON #{on_clause.join(' AND ')}"] # Same as: joins!(...)
|
784
|
-
end
|
793
|
+
end unless cust_col_override
|
785
794
|
while (n = nix.pop)
|
786
795
|
klass._br_hm_counts.delete(n)
|
787
796
|
end
|
@@ -851,6 +860,22 @@ JOIN (SELECT #{hm_selects.map { |s| "#{'br_t0.' if from_clause}#{s}" }.join(', '
|
|
851
860
|
wheres unless wheres.empty? # Return the specific parameters that we did use
|
852
861
|
end
|
853
862
|
|
863
|
+
# Build out an AR relation that queries for a list of objects, and include all the appropriate JOINs to later apply DSL using #brick_descrip
|
864
|
+
def brick_list
|
865
|
+
pks = klass.primary_key.is_a?(String) ? [klass.primary_key] : klass.primary_key
|
866
|
+
selects = pks.each_with_object([]) { |pk, s| s << pk unless s.include?(pk) }
|
867
|
+
# ActiveStorage compatibility
|
868
|
+
selects << 'service_name' if klass.name == 'ActiveStorage::Blob' && ActiveStorage::Blob.columns_hash.key?('service_name')
|
869
|
+
selects << 'blob_id' if klass.name == 'ActiveStorage::Attachment' && ActiveStorage::Attachment.columns_hash.key?('blob_id')
|
870
|
+
pieces, my_dsl = klass.brick_parse_dsl(join_array = ::Brick::JoinArray.new, [], translations = {}, false, nil, true)
|
871
|
+
brick_select(
|
872
|
+
where_values_hash, selects, nil, translations, join_array,
|
873
|
+
{ '_br' => (descrip_cols = [pieces, my_dsl]) }
|
874
|
+
)
|
875
|
+
order_values = klass.primary_key
|
876
|
+
[self.select(selects), descrip_cols]
|
877
|
+
end
|
878
|
+
|
854
879
|
private
|
855
880
|
|
856
881
|
def shift_or_first(ary)
|
@@ -1254,6 +1279,11 @@ class Object
|
|
1254
1279
|
end
|
1255
1280
|
self.abstract_class = true
|
1256
1281
|
code << " self.abstract_class = true\n"
|
1282
|
+
elsif Object.const_defined?('BCrypt') && relation[:cols].include?('password_digest') &&
|
1283
|
+
!instance_methods.include?(:password) && respond_to?(:has_secure_password)
|
1284
|
+
puts "Appears that the #{full_name} model is intended to hold user account information. Applying #has_secure_password."
|
1285
|
+
has_secure_password
|
1286
|
+
code << " has_secure_password\n"
|
1257
1287
|
end
|
1258
1288
|
# Accommodate singular or camel-cased table names such as "order_detail" or "OrderDetails"
|
1259
1289
|
code << " self.table_name = '#{self.table_name = matching}'\n" if inheritable_name || table_name != matching
|
@@ -2718,12 +2748,17 @@ module Brick
|
|
2718
2748
|
end
|
2719
2749
|
end
|
2720
2750
|
::Brick.relations.map do |k, v|
|
2751
|
+
# next if Brick.config.exclude_tables.include?(k)
|
2752
|
+
|
2721
2753
|
tbl_parts = k.split('.')
|
2722
2754
|
tbl_parts.shift if ::Brick.apartment_multitenant && tbl_parts.length > 1 && tbl_parts.first == ::Brick.apartment_default_tenant
|
2723
2755
|
res = tbl_parts.join('.')
|
2724
|
-
|
2725
|
-
|
2726
|
-
|
2756
|
+
table_name = (model = models[res])&.last&.table_name
|
2757
|
+
table_name ||= begin
|
2758
|
+
v[:class_name].constantize.table_name
|
2759
|
+
rescue
|
2760
|
+
end
|
2761
|
+
[k, table_name || k, migrations&.fetch(res, nil), model&.first]
|
2727
2762
|
end
|
2728
2763
|
end
|
2729
2764
|
|
@@ -58,7 +58,7 @@ module Brick
|
|
58
58
|
'(Add RGeo gem to parse geometry detail)'
|
59
59
|
end
|
60
60
|
when :binary
|
61
|
-
::Brick::Rails.display_binary(val)
|
61
|
+
::Brick::Rails.display_binary(val)
|
62
62
|
else
|
63
63
|
if col_type
|
64
64
|
::Brick::Rails::FormBuilder.hide_bcrypt(val, col_type == :xml)
|
@@ -69,8 +69,12 @@ module Brick
|
|
69
69
|
end
|
70
70
|
|
71
71
|
def display_binary(val)
|
72
|
+
return unless val
|
73
|
+
|
72
74
|
@image_signatures ||= { (+"\xFF\xD8\xFF\xEE").force_encoding('ASCII-8BIT') => 'jpeg',
|
73
75
|
(+"\xFF\xD8\xFF\xE0\x00\x10\x4A\x46\x49\x46\x00\x01").force_encoding('ASCII-8BIT') => 'jpeg',
|
76
|
+
(+"\xFF\xD8\xFF\xDB").force_encoding('ASCII-8BIT') => 'jpeg',
|
77
|
+
(+"\xFF\xD8\xFF\xE1").force_encoding('ASCII-8BIT') => 'jpeg',
|
74
78
|
(+"\x89PNG\r\n\x1A\n").force_encoding('ASCII-8BIT') => 'png',
|
75
79
|
'<svg' => 'svg+xml', # %%% Not yet very good detection for SVG
|
76
80
|
(+'BM').force_encoding('ASCII-8BIT') => 'bmp',
|
@@ -90,7 +94,8 @@ module Brick
|
|
90
94
|
val = val[object_start...object_start + real_object_size]
|
91
95
|
end
|
92
96
|
|
93
|
-
if (signature = @image_signatures.find { |k, _v| val[0...k.length] == k })
|
97
|
+
if (signature = @image_signatures.find { |k, _v| val[0...k.length] == k }) ||
|
98
|
+
(val[0..3] == 'RIFF' && val[8..11] == 'WEBP' && (signature = 'webp'))
|
94
99
|
if val.length < 500_000
|
95
100
|
"<img src=\"data:image/#{signature.last};base64,#{Base64.encode64(val)}\">"
|
96
101
|
else
|
@@ -1290,7 +1295,7 @@ erDiagram
|
|
1290
1295
|
</head>
|
1291
1296
|
<body>
|
1292
1297
|
<div id=\"titleBox\"><div id=\"titleSticky\">
|
1293
|
-
<p style=\"color: green\"><%= notice %></p>#{"
|
1298
|
+
<p style=\"color: green\"><%= notice if request.respond_to?(:flash) %></p>#{"
|
1294
1299
|
#{schema_options}" if schema_options}
|
1295
1300
|
<select id=\"tbl\">#{table_options}</select>
|
1296
1301
|
<table id=\"resourceName\"><tr>
|
@@ -1411,7 +1416,8 @@ end
|
|
1411
1416
|
brick_grid(@#{table_name}, @_brick_bt_descrip, @_brick_sequence, @_brick_incl, @_brick_excl,
|
1412
1417
|
cols, poly_cols, bts, #{hms_keys.inspect}, {#{hms_columns.join(', ')}}) %>
|
1413
1418
|
|
1414
|
-
#{"<hr><%= link_to
|
1419
|
+
#{"<hr><%= link_to(\"New #{new_path_name = "new_#{path_obj_name}_path"
|
1420
|
+
obj_name}\", #{new_path_name}) if respond_to?(:#{new_path_name}) %>" unless @_brick_model.is_view?}
|
1415
1421
|
#{script}
|
1416
1422
|
</body>
|
1417
1423
|
</html>
|
@@ -1423,7 +1429,7 @@ end
|
|
1423
1429
|
# Must load all models, and then find what table names are represented
|
1424
1430
|
# Easily could be multiple files involved (STI for instance)
|
1425
1431
|
+"#{css}
|
1426
|
-
<p style=\"color: green\"><%= notice %></p>#{"
|
1432
|
+
<p style=\"color: green\"><%= notice if request.respond_to?(:flash) %></p>#{"
|
1427
1433
|
#{schema_options}" if schema_options}
|
1428
1434
|
<select id=\"tbl\">#{table_options}</select>
|
1429
1435
|
<h1>Status</h1>
|
@@ -1473,7 +1479,7 @@ end
|
|
1473
1479
|
when 'orphans'
|
1474
1480
|
if is_orphans
|
1475
1481
|
+"#{css}
|
1476
|
-
<p style=\"color: green\"><%= notice %></p>#{"
|
1482
|
+
<p style=\"color: green\"><%= notice if request.respond_to?(:flash) %></p>#{"
|
1477
1483
|
#{schema_options}" if schema_options}
|
1478
1484
|
<select id=\"tbl\">#{table_options}</select>
|
1479
1485
|
<h1>Orphans<%= \" for #\{}\" if false %></h1>
|
@@ -1520,7 +1526,7 @@ end
|
|
1520
1526
|
c23.141-70.188,89.141-120.906,167.063-120.906c97.25,0,176,78.813,176,176C511.828,227.078,404.391,119.641,271.844,119.641z\" />
|
1521
1527
|
</svg>
|
1522
1528
|
|
1523
|
-
<p style=\"color: green\"><%= notice %></p>#{"
|
1529
|
+
<p style=\"color: green\"><%= notice if request.respond_to?(:flash) %></p>#{"
|
1524
1530
|
#{schema_options}" if schema_options}
|
1525
1531
|
<select id=\"tbl\">#{table_options}</select>
|
1526
1532
|
<table><td><h1><%= page_title %></h1></td>
|
@@ -1555,14 +1561,13 @@ end
|
|
1555
1561
|
%><%= link_to \"(See all #\{model_name.pluralize})\", see_all_path %>
|
1556
1562
|
#{erd_markup}
|
1557
1563
|
<% if obj
|
1558
|
-
|
1559
|
-
|
1560
|
-
|
1561
|
-
|
1562
|
-
|
1563
|
-
|
1564
|
-
|
1565
|
-
end
|
1564
|
+
# path_options = [obj.#{pk}]
|
1565
|
+
# path_options << { '_brick_schema': } if
|
1566
|
+
options = {}
|
1567
|
+
if ::Brick.config.path_prefix
|
1568
|
+
path_helper = obj.new_record? ? #{model_name}._brick_index : #{model_name}._brick_index(:singular)
|
1569
|
+
options[:url] = send(\"#\{path_helper}_path\".to_sym, obj)
|
1570
|
+
end
|
1566
1571
|
%>
|
1567
1572
|
<br><br>
|
1568
1573
|
<%= form_for(obj.becomes(#{model_name}), options) do |f| %>
|
@@ -1570,11 +1575,11 @@ end
|
|
1570
1575
|
<% has_fields = false
|
1571
1576
|
@#{obj_name}.attributes.each do |k, val|
|
1572
1577
|
next if !(col = #{model_name}.columns_hash[k]) ||
|
1573
|
-
(#{(pk || []).inspect}.include?(k) && !bts.key?(k)) ||
|
1578
|
+
(#{(pk.map(&:to_s) || []).inspect}.include?(k) && !bts.key?(k)) ||
|
1574
1579
|
::Brick.config.metadata_columns.include?(k) %>
|
1575
1580
|
<tr>
|
1576
1581
|
<th class=\"show-field\"<%= \" title=\\\"#\{col.comment}\\\"\".html_safe if col.respond_to?(:comment) && !col.comment.blank? %>>
|
1577
|
-
|
1582
|
+
<% has_fields = true
|
1578
1583
|
if (bt = bts[k])
|
1579
1584
|
# Add a final member in this array with descriptive options to be used in <select> drop-downs
|
1580
1585
|
bt_name = bt[1].map { |x| x.first.name }.join('/')
|
@@ -1602,7 +1607,15 @@ end
|
|
1602
1607
|
if bt.length < 4
|
1603
1608
|
bt << (option_detail = [[\"(No #\{bt_name\} chosen)\", '^^^brick_NULL^^^']])
|
1604
1609
|
# %%% Accommodate composite keys for obj.pk at the end here
|
1605
|
-
bt_class&.order(obj_pk = bt_class.primary_key)
|
1610
|
+
collection, descrip_cols = bt_class&.order(obj_pk = bt_class.primary_key).brick_list
|
1611
|
+
collection&.each do |obj|
|
1612
|
+
option_detail << [
|
1613
|
+
obj.brick_descrip(
|
1614
|
+
descrip_cols&.first&.map { |col| obj.send(col.last) },
|
1615
|
+
obj_pk
|
1616
|
+
), obj.send(obj_pk)
|
1617
|
+
]
|
1618
|
+
end
|
1606
1619
|
end %>
|
1607
1620
|
BT <%= bt_class&.bt_link(bt.first) || orig_poly_name %>
|
1608
1621
|
<% else %>
|
@@ -1619,7 +1632,11 @@ end
|
|
1619
1632
|
<% else %>
|
1620
1633
|
<tr><td colspan=\"2\">(No displayable fields)</td></tr>
|
1621
1634
|
<% end %>
|
1622
|
-
</table
|
1635
|
+
</table>#{
|
1636
|
+
"<%= binary = begin
|
1637
|
+
::Brick::Rails.display_binary(obj&.blob&.download)&.html_safe
|
1638
|
+
rescue
|
1639
|
+
end %>" if model_name == 'ActiveStorage::Attachment'}
|
1623
1640
|
<% end %>
|
1624
1641
|
|
1625
1642
|
#{unless args.first == 'new'
|
@@ -1634,34 +1651,51 @@ end
|
|
1634
1651
|
obj_pk = (pk.is_a?(Array) ? pk : [pk]).each_with_object([]) { |pk_part, s| s << "#{hm_singular_name}.#{pk_part}" }.join(', ')
|
1635
1652
|
poly_fix = if (poly_type = (hm.first.options[:as] && hm.first.type))
|
1636
1653
|
"
|
1637
|
-
|
1638
|
-
|
1639
|
-
|
1640
|
-
|
1641
|
-
|
1642
|
-
#{
|
1643
|
-
"
|
1644
|
-
|
1645
|
-
|
1646
|
-
|
1654
|
+
# Let's fix an unexpected \"feature\" of AR -- when going through a polymorphic has_many
|
1655
|
+
# association that points to an STI model then filtering for the __able_type column is done
|
1656
|
+
# with a .where(). And the polymorphic class name it points to is the base class name of
|
1657
|
+
# the STI model instead of its subclass.
|
1658
|
+
poly_type = #{poly_type.inspect}
|
1659
|
+
#{ (inh_col = @_brick_model.inheritance_column).present? &&
|
1660
|
+
" if poly_type && @#{obj_name}.respond_to?(:#{inh_col}) &&
|
1661
|
+
(base_type = collection.where_values_hash[poly_type])
|
1662
|
+
collection = collection.rewhere(poly_type => [base_type, @#{obj_name}.#{inh_col}])
|
1663
|
+
end"}"
|
1647
1664
|
end
|
1648
1665
|
s << "<table id=\"#{hm_name}\" class=\"shadow\">
|
1649
1666
|
<tr><th>#{hm[1]}#{' poly' if hm[0].options[:as]} #{hm[3]}</th></tr>
|
1650
|
-
<%
|
1651
|
-
|
1652
|
-
|
1653
|
-
|
1654
|
-
|
1655
|
-
|
1656
|
-
|
1657
|
-
|
1658
|
-
|
1659
|
-
|
1660
|
-
|
1667
|
+
<% if (assoc = @#{obj_name}.class.reflect_on_association(:#{hm_name})).macro == :has_one &&
|
1668
|
+
assoc.options&.fetch(:through, nil).nil?
|
1669
|
+
# In order to apply DSL properly, evaluate this HO the other way around as if it were as a BT
|
1670
|
+
collection = assoc.klass.where(assoc.foreign_key => @#{obj_name}.#{pk})
|
1671
|
+
collection = collection.instance_exec(&assoc.scopes.first) if assoc.scopes.present?
|
1672
|
+
if assoc.klass.name == 'ActiveStorage::Attachment'
|
1673
|
+
br_descrip = begin
|
1674
|
+
::Brick::Rails.display_binary(obj.send(assoc.name)&.blob&.download)&.html_safe
|
1675
|
+
rescue
|
1676
|
+
end
|
1677
|
+
end
|
1678
|
+
else
|
1679
|
+
collection = @#{obj_name}.#{hm_name}
|
1680
|
+
end
|
1681
|
+
case collection
|
1682
|
+
when ActiveRecord::Relation # has_many (which comes in as a CollectionProxy) or a has_one#{
|
1683
|
+
poly_fix}
|
1684
|
+
collection2, descrip_cols = collection.brick_list
|
1685
|
+
when ActiveRecord::Base # Object from a has_one :through
|
1686
|
+
collection2 = [collection]
|
1687
|
+
else # We get an array back when AR < 4.2
|
1688
|
+
collection2 = collection.to_a.compact
|
1689
|
+
end
|
1690
|
+
collection2 = collection2.uniq
|
1691
|
+
if collection2.empty? %>
|
1661
1692
|
<tr><td>(none)</td></tr>
|
1662
|
-
|
1663
|
-
|
1664
|
-
<tr><td><%=
|
1693
|
+
<% else
|
1694
|
+
collection2.each do |#{hm_singular_name}| %>
|
1695
|
+
<tr><td><%= br_descrip ||= #{hm_singular_name}.brick_descrip(
|
1696
|
+
descrip_cols&.first&.map { |col| #{hm_singular_name}.send(col.last) }
|
1697
|
+
)
|
1698
|
+
link_to(br_descrip, #{hm.first.klass._brick_index(:singular)}_path(slashify(#{obj_pk}))) %></td></tr>
|
1665
1699
|
<% end %>
|
1666
1700
|
<% end %>
|
1667
1701
|
</table>"
|
@@ -115,7 +115,14 @@ module Brick::Rails::FormTags
|
|
115
115
|
if col[2] == 'HO'
|
116
116
|
descrips = bt_descrip[col_name.to_sym][hm_klass]
|
117
117
|
if (ho_id = (ho_id_col = descrips.last).map { |id_col| obj.send(id_col.to_sym) })&.first
|
118
|
-
ho_txt = hm_klass.
|
118
|
+
ho_txt = if hm_klass.name == 'ActiveStorage::Attachment'
|
119
|
+
begin
|
120
|
+
::Brick::Rails.display_binary(obj.send(col[3])&.blob&.download)&.html_safe
|
121
|
+
rescue
|
122
|
+
end
|
123
|
+
else
|
124
|
+
hm_klass.brick_descrip(obj, descrips[0..-2].map { |id| obj.send(id.last[0..62]) }, ho_id_col)
|
125
|
+
end
|
119
126
|
out << link_to(ho_txt, send("#{hm_klass.base_class._brick_index(:singular)}_path".to_sym, ho_id))
|
120
127
|
end
|
121
128
|
else
|
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.129
|
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-04-
|
11
|
+
date: 2023-04-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|