brick 1.0.127 → 1.0.129
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 +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
|