brick 1.0.210 → 1.0.211
Sign up to get free protection for your applications and to get access to all the features.
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
|