brick 1.0.210 → 1.0.211
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
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7950119f788fe1cac3fde68806f2b4a1145da0cf17ff0d47363b102be9c69933
|
4
|
+
data.tar.gz: 33bb7d89a0744890d4450afde332dbd0f0635a8d3acd0beb4107cf4e44ff9718
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 959c6ada7e03de34f566ad6059a4431ea66d2be9f12764de3edb3760074a70f3e91354e9052bc3c1a74eed4d5d7a274a78cf490195815b736b02f282ffe03d47
|
7
|
+
data.tar.gz: a87abaf8c878fecda93fc6751bae171e5194b6b63d933f83ba331191aee701859d3022754f68af3d730c25add0cc0a8174246fd18913040bed75ec700ba2b543
|
data/lib/brick/extensions.rb
CHANGED
@@ -92,11 +92,49 @@ module ActiveRecord
|
|
92
92
|
reflect_on_association(assoc).foreign_type || "#{assoc}_type"
|
93
93
|
end
|
94
94
|
|
95
|
-
def _brick_all_fields
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
95
|
+
def _brick_all_fields(skip_id = nil)
|
96
|
+
col_names = columns_hash.keys
|
97
|
+
# If it's a composite primary key then allow all the values through
|
98
|
+
# TODO: Should disallow any autoincrement / SERIAL columns
|
99
|
+
if skip_id && (pk_as_array = _pk_as_array).length == 1
|
100
|
+
col_names -= _pk_as_array
|
101
|
+
end
|
102
|
+
hoa, hma, rtans = _activestorage_actiontext_fields
|
103
|
+
col_names.map(&:to_sym) + hoa + hma.map { |as| { as => [] } } + rtans.values
|
104
|
+
end
|
105
|
+
|
106
|
+
# Return three lists of fields for this model --
|
107
|
+
# has_one_attached, has_many_attached, and has_rich_text
|
108
|
+
def _activestorage_actiontext_fields
|
109
|
+
fields = [[], [], {}]
|
110
|
+
if !(self <= ActiveStorage::Blob) && respond_to?(:generated_association_methods) # ActiveStorage
|
111
|
+
generated_association_methods.instance_methods.each do |method_sym|
|
112
|
+
method_str = method_sym.to_s
|
113
|
+
fields[0] << method_str[0..-13].to_sym if method_str.end_with?('_attachment=') # has_one_attached
|
114
|
+
fields[1] << method_str[0..-14].to_sym if method_str.end_with?('_attachments=') # has_many_attached
|
115
|
+
end
|
116
|
+
end
|
117
|
+
if respond_to?(:rich_text_association_names) # ActionText
|
118
|
+
rich_text_association_names&.each do |rtan| # has_rich_text
|
119
|
+
rtan_str = rtan.to_s
|
120
|
+
fields[2][rtan] = rtan_str.start_with?('rich_text_') ? rtan_str[10..-1].to_sym : rtan
|
121
|
+
end
|
122
|
+
end
|
123
|
+
fields
|
124
|
+
end
|
125
|
+
|
126
|
+
def _active_storage_name(col_name)
|
127
|
+
if Object.const_defined?('ActiveStorage') && (self <= ActiveStorage::Attachment || self <= ActiveStorage::Blob)
|
128
|
+
if (col_str = col_name.to_s).end_with?('_attachments')
|
129
|
+
col_str[0..-13]
|
130
|
+
elsif col_str.end_with?('_blobs')
|
131
|
+
col_str[0..-7]
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
def _pk_as_array
|
137
|
+
self.primary_key.is_a?(Array) ? self.primary_key : [self.primary_key]
|
100
138
|
end
|
101
139
|
|
102
140
|
def _br_quoted_name(name)
|
@@ -147,8 +185,8 @@ module ActiveRecord
|
|
147
185
|
skip_columns = _brick_get_fks + (::Brick.config.metadata_columns || []) + [primary_key]
|
148
186
|
dsl = if (descrip_col = columns.find { |c| [:boolean, :binary, :xml].exclude?(c.type) && skip_columns.exclude?(c.name) })
|
149
187
|
"[#{descrip_col.name}]"
|
150
|
-
|
151
|
-
"#{name} ##{
|
188
|
+
else
|
189
|
+
"#{name} ##{_pk_as_array.map { |pk_part| "[#{pk_part}]" }.join(', ')}"
|
152
190
|
end
|
153
191
|
::Brick.config.model_descrips[name] = dsl
|
154
192
|
end
|
@@ -841,6 +879,8 @@ module ActiveRecord
|
|
841
879
|
end
|
842
880
|
through_sources.push(src_ref) unless src_ref.belongs_to?
|
843
881
|
from_clause = +"#{_br_quoted_name(through_sources.first.table_name)} br_t0"
|
882
|
+
# ActiveStorage will not get the correct count unless we do some extra filtering later
|
883
|
+
tbl_nm = 'br_t0' if Object.const_defined?('ActiveStorage') && through_sources.first.klass <= ActiveStorage::Attachment
|
844
884
|
fk_col = through_sources.shift.foreign_key
|
845
885
|
|
846
886
|
idx = 0
|
@@ -934,10 +974,14 @@ module ActiveRecord
|
|
934
974
|
tbl_nm = hm.macro == :has_and_belongs_to_many ? hm.join_table : hm.table_name
|
935
975
|
hm_table_name = _br_quoted_name(tbl_nm)
|
936
976
|
end
|
977
|
+
# ActiveStorage has_many_attached needs a bit more filtering
|
978
|
+
if (k_str = hm.klass._active_storage_name(k))
|
979
|
+
where_ct_clause = "WHERE #{_br_quoted_name("#{tbl_nm}.name")} = '#{k_str}' "
|
980
|
+
end
|
937
981
|
group_bys = ::Brick.is_oracle || is_mssql ? hm_selects : (1..hm_selects.length).to_a
|
938
982
|
join_clause = "LEFT OUTER
|
939
983
|
JOIN (SELECT #{hm_selects.map { |s| _br_quoted_name("#{'br_t0.' if from_clause}#{s}") }.join(', ')}, COUNT(#{'DISTINCT ' if hm.options[:through]}#{_br_quoted_name(count_column)
|
940
|
-
}) AS c_t_ FROM #{from_clause || hm_table_name} GROUP BY #{group_bys.join(', ')}) #{_br_quoted_name(tbl_alias)}"
|
984
|
+
}) AS c_t_ FROM #{from_clause || hm_table_name} #{where_ct_clause}GROUP BY #{group_bys.join(', ')}) #{_br_quoted_name(tbl_alias)}"
|
941
985
|
self.joins_values |= ["#{join_clause} ON #{on_clause.join(' AND ')}"] # Same as: joins!(...)
|
942
986
|
end unless cust_col_override
|
943
987
|
while (n = nix.pop)
|
@@ -2369,6 +2413,8 @@ class Object
|
|
2369
2413
|
end
|
2370
2414
|
end
|
2371
2415
|
|
2416
|
+
params_name_sym = (params_name = "#{singular_table_name}_params").to_sym
|
2417
|
+
|
2372
2418
|
# By default, views get marked as read-only
|
2373
2419
|
# unless model.readonly # (relation = relations[model.table_name]).key?(:isView)
|
2374
2420
|
code << " def new\n"
|
@@ -2376,7 +2422,11 @@ class Object
|
|
2376
2422
|
code << " end\n"
|
2377
2423
|
self.define_method :new do
|
2378
2424
|
_schema, @_is_show_schema_list = ::Brick.set_db_schema(params)
|
2379
|
-
new_params =
|
2425
|
+
new_params = begin
|
2426
|
+
send(params_name_sym)
|
2427
|
+
rescue
|
2428
|
+
end
|
2429
|
+
new_params ||= model.attribute_names.each_with_object({}) do |a, s|
|
2380
2430
|
if (val = params["__#{a}"])
|
2381
2431
|
# val = case new_obj.class.column_for_attribute(a).type
|
2382
2432
|
# when :datetime, :date, :time, :timestamp
|
@@ -2397,8 +2447,6 @@ class Object
|
|
2397
2447
|
add_csp_hash
|
2398
2448
|
end
|
2399
2449
|
|
2400
|
-
params_name_sym = (params_name = "#{singular_table_name}_params").to_sym
|
2401
|
-
|
2402
2450
|
code << " def create\n"
|
2403
2451
|
code << " @#{singular_table_name} = #{model.name}.create(#{params_name})\n"
|
2404
2452
|
code << " end\n"
|
@@ -2415,8 +2463,7 @@ class Object
|
|
2415
2463
|
end
|
2416
2464
|
render json: { result: ::Brick.unexclude_column(table_name, col) }
|
2417
2465
|
else
|
2418
|
-
|
2419
|
-
(created_obj = model.send(:create, send(params_name_sym))))
|
2466
|
+
created_obj = model.send(:create, send(params_name_sym))
|
2420
2467
|
@_lookup_context.instance_variable_set(:@_brick_model, model)
|
2421
2468
|
if created_obj.errors.empty?
|
2422
2469
|
index
|
@@ -2493,7 +2540,16 @@ class Object
|
|
2493
2540
|
if (upd_hash ||= upd_params).fetch(model.inheritance_column, nil)&.strip == ''
|
2494
2541
|
upd_hash[model.inheritance_column] = nil
|
2495
2542
|
end
|
2496
|
-
|
2543
|
+
# Do not clear out a has_many_attached field if it already has an entry and nothing is supplied
|
2544
|
+
hoa, hma, rtans = model._activestorage_actiontext_fields
|
2545
|
+
all_params = params[singular_table_name]
|
2546
|
+
hma.each do |hma_field|
|
2547
|
+
if upd_hash.fetch(hma_field) == [''] && # No new attachments...
|
2548
|
+
all_params&.fetch("_brick_attached_#{hma_field}", nil) # ...and there is something existing
|
2549
|
+
upd_hash.delete(hma_field)
|
2550
|
+
end
|
2551
|
+
end
|
2552
|
+
obj.send(:update, upd_hash)
|
2497
2553
|
if obj.errors.any? # Surface errors to the user in a flash message
|
2498
2554
|
flash.now.alert = (obj.errors.errors.map { |err| "<b>#{err.attribute}</b> #{err.message}" }.join(', '))
|
2499
2555
|
end
|
@@ -2543,7 +2599,7 @@ class Object
|
|
2543
2599
|
|
2544
2600
|
if is_need_params
|
2545
2601
|
code << " def #{params_name}\n"
|
2546
|
-
permits_txt = model._brick_find_permits(model, permits = model._brick_all_fields)
|
2602
|
+
permits_txt = model._brick_find_permits(model, permits = model._brick_all_fields(true))
|
2547
2603
|
code << " params.require(:#{require_name = model.name.underscore.tr('/', '_')
|
2548
2604
|
}).permit(#{permits_txt.map(&:inspect).join(', ')})\n"
|
2549
2605
|
code << " end\n"
|
@@ -641,6 +641,11 @@ window.addEventListener(\"popstate\", linkSchemas);
|
|
641
641
|
type_col = hm_assoc.inverse_of&.foreign_type || hm_assoc.type
|
642
642
|
keys << [type_col, poly_type]
|
643
643
|
end
|
644
|
+
# ActiveStorage has_one_attached and has_many_attached needs additional filtering on the name
|
645
|
+
if (as_name = hm_assoc.klass&._active_storage_name(hm_assoc.name)) # ActiveStorage HMT
|
646
|
+
prefix = 'attachments.' if hm_assoc.through_reflection&.klass&.<= ActiveStorage::Attachment
|
647
|
+
keys << ["#{prefix}name", as_name]
|
648
|
+
end
|
644
649
|
keys.to_h
|
645
650
|
end
|
646
651
|
|
@@ -1506,7 +1511,7 @@ end
|
|
1506
1511
|
|
1507
1512
|
if (pk = hm.first.klass.primary_key)
|
1508
1513
|
hm_singular_name = (hm_name = hm.first.name.to_s).singularize.underscore
|
1509
|
-
obj_br_pk =
|
1514
|
+
obj_br_pk = hm.first.klass._pk_as_array.map { |pk_part| "br_#{hm_singular_name}.#{pk_part}" }.join(', ')
|
1510
1515
|
poly_fix = if (poly_type = (hm.first.options[:as] && hm.first.type))
|
1511
1516
|
"
|
1512
1517
|
# Let's fix an unexpected \"feature\" of AR -- when going through a polymorphic has_many
|
@@ -110,6 +110,41 @@ module Brick::Rails::FormBuilder
|
|
110
110
|
::Brick::Rails.display_binary(val)
|
111
111
|
end
|
112
112
|
end
|
113
|
+
when :file, :files
|
114
|
+
if attached = begin
|
115
|
+
self.object.send(method)
|
116
|
+
rescue
|
117
|
+
end
|
118
|
+
# Show any existing image(s)
|
119
|
+
existing = []
|
120
|
+
got_one = nil
|
121
|
+
(attached.respond_to?(:attachments) ? attached.attachments : [attached]).each do |attachment|
|
122
|
+
next unless (blob = attachment.blob)
|
123
|
+
|
124
|
+
existing << blob.key
|
125
|
+
out << "#{blob.filename}<br>"
|
126
|
+
url = begin
|
127
|
+
self.object.send(method)&.url
|
128
|
+
rescue StandardError => e
|
129
|
+
# Another possible option:
|
130
|
+
# Rails.application.routes.url_helpers.rails_blob_path(attachment, only_path: true)
|
131
|
+
Rails.application.routes.url_helpers.rails_storage_proxy_path(attachment, only_path: true)
|
132
|
+
end
|
133
|
+
out << if url
|
134
|
+
"<img src=\"#{url}\" title=\"#{val}\">"
|
135
|
+
else # Convert the raw binary to a Base64 image
|
136
|
+
::Brick::Rails.display_binary(attachment.download, 500_000)
|
137
|
+
end
|
138
|
+
got_one = true
|
139
|
+
out << '<br>'
|
140
|
+
end
|
141
|
+
out << 'Update: ' if got_one
|
142
|
+
end
|
143
|
+
out << self.hidden_field("_brick_attached_#{method}", value: existing.join(',')) unless existing.blank?
|
144
|
+
# Render a "Choose File(s)" input element
|
145
|
+
args = [method.to_sym]
|
146
|
+
args << { multiple: true } if col&.type == :files
|
147
|
+
out << self.file_field(*args)
|
113
148
|
when :primary_key
|
114
149
|
is_revert = false
|
115
150
|
when :json, :jsonb
|
@@ -445,19 +445,25 @@ function onImagesLoaded(event) {
|
|
445
445
|
obj.send("#{model.brick_foreign_type(v.first)}=", v[1].first&.first&.name)
|
446
446
|
end
|
447
447
|
end if obj.new_record?
|
448
|
-
rtans = model.
|
449
|
-
(model.column_names +
|
448
|
+
hoa, hma, rtans = model._activestorage_actiontext_fields
|
449
|
+
(model.column_names + hoa + hma + rtans.keys).each do |k|
|
450
450
|
pk_pos = (pk.index(k)&.+ 1)
|
451
451
|
next if (pk_pos && pk.length == 1 && !bts.key?(k)) ||
|
452
452
|
::Brick.config.metadata_columns.include?(k)
|
453
453
|
|
454
454
|
col = model.columns_hash[k]
|
455
|
-
if !col
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
455
|
+
if !col
|
456
|
+
kwargs = if hoa.include?(k) # has_one_attached
|
457
|
+
{ sql_type: 'binary', type: :file }
|
458
|
+
elsif hma.include?(k) # has_many_attached
|
459
|
+
{ sql_type: 'binary', type: :files }
|
460
|
+
elsif rtans&.key?(k) # has_rich_text
|
461
|
+
k = rtans[k]
|
462
|
+
{ sql_type: 'varchar', type: :text }
|
463
|
+
end
|
464
|
+
col = (ActiveRecord::ConnectionAdapters::Column.new(
|
465
|
+
'', nil, ActiveRecord::ConnectionAdapters::SqlTypeMetadata.new(**kwargs)
|
466
|
+
)) if kwargs
|
461
467
|
end
|
462
468
|
val = obj.attributes[k]
|
463
469
|
out << "
|
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.211
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lorin Thwaits
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-03-
|
11
|
+
date: 2024-03-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|