brick 1.0.245 → 1.0.246
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 +66 -59
- data/lib/brick/rails/engine.rb +37 -25
- data/lib/brick/rails/form_tags.rb +23 -12
- data/lib/brick/rails.rb +1 -1
- data/lib/brick/reflect_tables.rb +1 -2
- data/lib/brick/version_number.rb +1 -1
- metadata +3 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 3410ae5fca9b12aa31007df9d3fac95a39f09eee58f4ffc2089bada97bde7793
|
|
4
|
+
data.tar.gz: 0da56c9311d8dd0ce2fd3a05039a6f85ca9910c64b303c25fc26f8d65fab512b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7a2e821dfee25a5df265caf5700e25003cbc7cab88e439102fc949f5dfbba2f9f7b73803c98068d373ffbf12cab27dac3859c76a7772ea19bbaf4ffdbfbddbe6
|
|
7
|
+
data.tar.gz: 701d6d9e7d374cbe850806ce732f5b765c1ea3d051c111f316bcd29fdf45622d8999c04fa89ca058f13052670f56c77350fde24e00139ef40dc892b0c97ca896
|
data/lib/brick/extensions.rb
CHANGED
|
@@ -162,7 +162,7 @@ module ActiveRecord
|
|
|
162
162
|
def _brick_deserialized_id(obj, id_col)
|
|
163
163
|
id = []
|
|
164
164
|
self._pk_as_array.each_with_index do |pk_part, idx|
|
|
165
|
-
id << if
|
|
165
|
+
id << if (id_sym = id_col[idx]&.to_sym) && obj.respond_to?(id_sym)
|
|
166
166
|
self._brick_deserialized_value(obj, [[pk_part, id_col[idx]]])&.first
|
|
167
167
|
else
|
|
168
168
|
id_col[idx]
|
|
@@ -926,11 +926,13 @@ module ActiveRecord
|
|
|
926
926
|
poly_ft = [hm.source_reflection.inverse_of.foreign_type, hmt_assoc.source_reflection.class_name]
|
|
927
927
|
end
|
|
928
928
|
# link_back << hm.source_reflection.inverse_of.name
|
|
929
|
-
while hmt_assoc.options[:through] && (hmt_assoc = klass.reflect_on_association(hmt_assoc.options[:through]))
|
|
929
|
+
while hmt_assoc.options[:through] && (hmt_assoc = klass.reflect_on_association(xy = hmt_assoc.options[:through]))
|
|
930
|
+
if hmt_assoc.macro == :has_and_belongs_to_many
|
|
931
|
+
through_sources.unshift(hmt_assoc)
|
|
932
|
+
link_back << hmt_assoc.source_reflection.klass.reflect_on_all_associations.find { |a| a.macro == :has_and_belongs_to_many && a.join_table == hmt_assoc.join_table }.name
|
|
933
|
+
end
|
|
930
934
|
through_sources.unshift(hmt_assoc)
|
|
931
935
|
end
|
|
932
|
-
# Turn the last member of link_back into a foreign key
|
|
933
|
-
link_back << hmt_assoc.source_reflection.foreign_key
|
|
934
936
|
# If it's a HMT based on a HM -> HM, must JOIN the last table into the mix at the end
|
|
935
937
|
this_hm = hm
|
|
936
938
|
while !(src_ref = this_hm.source_reflection).belongs_to? && (thr = src_ref.options[:through])
|
|
@@ -940,39 +942,48 @@ module ActiveRecord
|
|
|
940
942
|
from_clause = +"#{_br_quoted_name(through_sources.first.table_name)} br_t0"
|
|
941
943
|
# ActiveStorage will not get the correct count unless we do some extra filtering later
|
|
942
944
|
tbl_nm = 'br_t0' if Object.const_defined?('ActiveStorage') && through_sources.first.klass <= ::ActiveStorage::Attachment
|
|
943
|
-
|
|
944
|
-
|
|
945
|
+
# Turn the last member of link_back into a foreign key
|
|
946
|
+
link_back << ((tsf = through_sources.shift).macro == :has_and_belongs_to_many ?
|
|
947
|
+
tsf.klass.primary_key : hmt_assoc.source_reflection.foreign_key)
|
|
948
|
+
fk_col = tsf.macro == :has_and_belongs_to_many ?
|
|
949
|
+
tsf.klass.primary_key : tsf.foreign_key
|
|
945
950
|
idx = 0
|
|
946
951
|
bail_out = nil
|
|
947
952
|
the_chain = through_sources.map do |a|
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
"br_t#{idx
|
|
953
|
+
puts "#{a.name} - #{a.macro}"
|
|
954
|
+
if a.macro == :has_and_belongs_to_many
|
|
955
|
+
from_clause << "\n LEFT OUTER JOIN #{a.join_table} br_t#{idx += 1} ON br_t#{idx}.#{a.association_foreign_key} = br_t#{idx - 1}.#{a.active_record.primary_key}"
|
|
956
|
+
from_clause << "\n LEFT OUTER JOIN #{a.active_record.table_name} br_t#{idx += 1} ON br_t#{idx}.#{a.active_record.primary_key} = br_t#{idx - 1}.#{a.foreign_key}"
|
|
957
|
+
else
|
|
958
|
+
from_clause << "\n LEFT OUTER JOIN #{a.table_name} br_t#{idx += 1} "
|
|
959
|
+
from_clause << if (src_ref = a.source_reflection).macro == :belongs_to
|
|
960
|
+
link_back << (nm = hmt_assoc.source_reflection.inverse_of&.name)
|
|
961
|
+
# puts "BT #{a.table_name}"
|
|
962
|
+
"ON br_t#{idx}.#{a.active_record.primary_key} = br_t#{idx - 1}.#{a.foreign_key}"
|
|
963
|
+
elsif src_ref.options[:as]
|
|
964
|
+
"ON br_t#{idx}.#{src_ref.type} = '#{src_ref.active_record.name}'" + # "polymorphable_type"
|
|
965
|
+
" AND br_t#{idx}.#{src_ref.foreign_key} = br_t#{idx - 1}.id"
|
|
966
|
+
elsif src_ref.options[:source_type]
|
|
967
|
+
if a == hm.source_reflection
|
|
968
|
+
print "Skipping #{hm.name} --HMT-> #{hm.source_reflection.name} as it uses source_type in a way which is not yet supported"
|
|
969
|
+
nix << k
|
|
970
|
+
bail_out = true
|
|
971
|
+
break
|
|
972
|
+
# "ON br_t#{idx}.#{a.foreign_type} = '#{src_ref.options[:source_type]}' AND " \
|
|
973
|
+
# "br_t#{idx}.#{a.foreign_key} = br_t#{idx - 1}.#{a.active_record.primary_key}"
|
|
974
|
+
else # Works for HMT through a polymorphic HO
|
|
975
|
+
link_back << hmt_assoc.source_reflection.inverse_of&.name # Some polymorphic "_able" thing
|
|
976
|
+
"ON br_t#{idx - 1}.#{a.foreign_type} = '#{src_ref.options[:source_type]}' AND " \
|
|
977
|
+
"br_t#{idx - 1}.#{a.foreign_key} = br_t#{idx}.#{a.active_record.primary_key}"
|
|
978
|
+
end
|
|
979
|
+
else # Standard has_many or has_one
|
|
980
|
+
# puts "HM #{a.table_name}"
|
|
981
|
+
nm = hmt_assoc.source_reflection.inverse_of&.name
|
|
982
|
+
# binding.pry unless nm
|
|
983
|
+
link_back << nm # if nm
|
|
984
|
+
"ON br_t#{idx}.#{a.foreign_key} = br_t#{idx - 1}.#{a.active_record.primary_key}"
|
|
968
985
|
end
|
|
969
|
-
|
|
970
|
-
# puts "HM #{a.table_name}"
|
|
971
|
-
nm = hmt_assoc.source_reflection.inverse_of&.name
|
|
972
|
-
# binding.pry unless nm
|
|
973
|
-
link_back << nm # if nm
|
|
974
|
-
"ON br_t#{idx}.#{a.foreign_key} = br_t#{idx - 1}.#{a.active_record.primary_key}"
|
|
975
|
-
end
|
|
986
|
+
end
|
|
976
987
|
link_back.unshift(a.source_reflection.name)
|
|
977
988
|
[a.table_name, a.foreign_key, a.source_reflection.macro]
|
|
978
989
|
end
|
|
@@ -980,7 +991,9 @@ module ActiveRecord
|
|
|
980
991
|
|
|
981
992
|
# puts "LINK BACK! #{k} : #{hm.table_name} #{link_back.map(&:to_s).join('.')}"
|
|
982
993
|
# count_column is determined from the originating HMT member
|
|
983
|
-
if
|
|
994
|
+
if hmt_assoc.macro == :has_and_belongs_to_many
|
|
995
|
+
"br_t#{idx}.#{src_ref.active_record.primary_key}"
|
|
996
|
+
elsif (src_ref = hm.source_reflection).nil?
|
|
984
997
|
puts "*** Warning: Could not determine destination model for this HMT association in model #{klass.name}:\n has_many :#{hm.name}, through: :#{hm.options[:through]}"
|
|
985
998
|
puts
|
|
986
999
|
nix << k
|
|
@@ -2162,7 +2175,9 @@ class Object
|
|
|
2162
2175
|
# (More information on https://docs.avohq.io/3.0/controllers.html)
|
|
2163
2176
|
controller_base = Avo::ResourcesController
|
|
2164
2177
|
end
|
|
2165
|
-
if
|
|
2178
|
+
if model && !(model < ActiveRecord::Base)
|
|
2179
|
+
raise "Your project defines class \"#{model.name}\" which is not an ActiveRecord model. If some other model class for this resource exists that can be used instead, you can configure a Brick table_name_prefix in order to have a specific table name refer to that class."
|
|
2180
|
+
elsif !model&.table_exists? && (tn = model&.table_name)
|
|
2166
2181
|
msg = +"Can't find table \"#{tn}\" for model #{model.name}."
|
|
2167
2182
|
puts
|
|
2168
2183
|
# Potential bad inflection?
|
|
@@ -2706,7 +2721,6 @@ class Object
|
|
|
2706
2721
|
# ActiveRecord::Base.execute_sql("SET SEARCH_PATH = ?;", schema)
|
|
2707
2722
|
# end
|
|
2708
2723
|
|
|
2709
|
-
is_need_params = true
|
|
2710
2724
|
code << " def edit\n"
|
|
2711
2725
|
code << " #{find_by_name}\n"
|
|
2712
2726
|
code << " end\n"
|
|
@@ -2799,7 +2813,7 @@ class Object
|
|
|
2799
2813
|
end
|
|
2800
2814
|
end
|
|
2801
2815
|
|
|
2802
|
-
code << "private\n"
|
|
2816
|
+
code << "private\n"
|
|
2803
2817
|
|
|
2804
2818
|
if pk.present?
|
|
2805
2819
|
code << " def #{find_obj}
|
|
@@ -2829,29 +2843,23 @@ class Object
|
|
|
2829
2843
|
private find_obj
|
|
2830
2844
|
end
|
|
2831
2845
|
|
|
2832
|
-
|
|
2833
|
-
|
|
2834
|
-
|
|
2835
|
-
|
|
2836
|
-
|
|
2837
|
-
|
|
2838
|
-
|
|
2839
|
-
|
|
2840
|
-
|
|
2841
|
-
|
|
2842
|
-
|
|
2843
|
-
|
|
2844
|
-
|
|
2845
|
-
code << " params.require(:#{require_txt
|
|
2846
|
-
}).permit(#{permits_txt.map(&:inspect).join(', ')})\n"
|
|
2847
|
-
code << " end\n"
|
|
2848
|
-
self.define_method(params_name) do
|
|
2849
|
-
params.require(model.base_class.name.underscore.tr('/', '_').to_sym).permit(permits)
|
|
2850
|
-
end
|
|
2846
|
+
code << " def #{params_name}\n"
|
|
2847
|
+
require_txt = model.base_class.name.underscore.tr('/', '_')
|
|
2848
|
+
is_for_expects = ::ActiveSupport.version >= ::Gem::Version.new('8.0a')
|
|
2849
|
+
permits_txt = model._brick_find_permits(model, permits = model._brick_all_fields(true), is_for_expects)
|
|
2850
|
+
if is_for_expects
|
|
2851
|
+
code << " params.expect(#{require_txt}: #{permits_txt})\n"
|
|
2852
|
+
self.define_method(params_name) do
|
|
2853
|
+
params.expect({ model.base_class.name.underscore.tr('/', '_').to_sym => permits })
|
|
2854
|
+
end
|
|
2855
|
+
else
|
|
2856
|
+
code << " params.require(:#{require_txt}).permit(#{permits_txt.map(&:inspect).join(', ')})\n"
|
|
2857
|
+
self.define_method(params_name) do
|
|
2858
|
+
params.require(model.base_class.name.underscore.tr('/', '_').to_sym).permit(permits)
|
|
2851
2859
|
end
|
|
2852
|
-
private params_name
|
|
2853
|
-
# Get column names for params from relations[model.table_name][:cols].keys
|
|
2854
2860
|
end
|
|
2861
|
+
code << " end\n"
|
|
2862
|
+
private params_name
|
|
2855
2863
|
end # unless is_openapi
|
|
2856
2864
|
code << "end # #{class_name}\n"
|
|
2857
2865
|
end # class definition
|
|
@@ -3210,7 +3218,6 @@ module Brick
|
|
|
3210
3218
|
end
|
|
3211
3219
|
end
|
|
3212
3220
|
abstract_activerecord_bases = ::Brick.eager_load_classes(true)
|
|
3213
|
-
rails_root = ::Rails.root.to_s
|
|
3214
3221
|
models = ::Brick.relations.each_with_object({}) do |rel, s|
|
|
3215
3222
|
next if rel.first.is_a?(Symbol)
|
|
3216
3223
|
|
data/lib/brick/rails/engine.rb
CHANGED
|
@@ -826,20 +826,24 @@ window.addEventListener(\"popstate\", linkSchemas);
|
|
|
826
826
|
['Crosstab', is_crosstab]].each do |table_option, show_it|
|
|
827
827
|
table_options << "<option value=\"#{prefix}brick_#{table_option.downcase}\">(#{table_option})</option>".html_safe if show_it
|
|
828
828
|
end
|
|
829
|
-
css = +"
|
|
830
|
-
|
|
829
|
+
css = +"
|
|
830
|
+
<%
|
|
831
831
|
if @_request.respond_to?(:content_security_policy) && (csp = @_request.content_security_policy)&.directives&.present?
|
|
832
832
|
@_request.env['_is_brick'] = true
|
|
833
833
|
if @_request.respond_to?(:content_security_policy_nonce_directives)
|
|
834
834
|
@_request.content_security_policy_nonce_directives = %w[ script-src ]
|
|
835
835
|
@_request.env['_brick_nonce'] = \" nonce=\\\"#\{@_request.content_security_policy_nonce}\\\"\".html_safe
|
|
836
|
+
%><meta name=\"csp-nonce\" content=\"<%= @_request.content_security_policy_nonce %>\"><%
|
|
836
837
|
end
|
|
837
838
|
if !@_request.respond_to?(:_brick_content_security_policy)
|
|
838
839
|
if csp.instance_variables.exclude?(:@_brick_style_shas)
|
|
839
840
|
csp.instance_variable_set(:@_brick_style_shas, [
|
|
840
841
|
\"'sha256-#\{Base64.encode64(Digest.const_get(:SHA256).digest(::Brick::Rails::BRICK_CSS)).chomp}'\",
|
|
841
842
|
\"'sha256-#\{Base64.encode64(Digest.const_get(:SHA256).digest(::Brick::Rails::IN_APP_STYLE)).chomp}'\",
|
|
842
|
-
\"'sha256-y+oXtN5Bag5VRQgH6D87Eo4UdOZOJiqg31ZNfDibDwM='\" # SHA for the text_field used in brick_field ('min-width: 154px;field-sizing: content;')
|
|
843
|
+
\"'sha256-y+oXtN5Bag5VRQgH6D87Eo4UdOZOJiqg31ZNfDibDwM='\", # SHA for the text_field used in brick_field ('min-width: 154px;field-sizing: content;')
|
|
844
|
+
\"'sha256-aOKu38ec/bSbd1BWfOZWow6kP78MsLOsTmNyCpYqsXM='\", # SHA for Mermaid ('font-family: Arial')
|
|
845
|
+
\"'sha256-P8hbc8HpnNaBWbGVqO8n4uIP3lIM4rGog3PnEYWwrzQ='\" # SHA for flatpickr calendar ('.flatpickr-calendar {background: #A0FFA0;}')
|
|
846
|
+
# \"'sha256-oU3/kVZLL/AmlO0Oi4iZplNUwV9XJW7qt6J9Mm2ASNs='\" # SHA for Mermaid (SVG things)
|
|
843
847
|
])
|
|
844
848
|
end
|
|
845
849
|
|
|
@@ -850,18 +854,18 @@ window.addEventListener(\"popstate\", linkSchemas);
|
|
|
850
854
|
|
|
851
855
|
csp = ::ActionDispatch::ContentSecurityPolicy.new
|
|
852
856
|
csp.directives.merge! ({
|
|
853
|
-
'style-src': [\"'self'\", 'https://cdn.jsdelivr.net', \"'unsafe-hashes'\"] +
|
|
857
|
+
'style-src': [\"'self'\", 'https://cdn.jsdelivr.net', \"'unsafe-hashes'\", \"'nonce-#\{content_security_policy_nonce}'\"] +
|
|
854
858
|
_brick_content_security_policy.instance_variable_get(:@_brick_style_shas),
|
|
855
|
-
'script-src': [\"'self'\", 'https://cdn.jsdelivr.net', \"'nonce-#\{content_security_policy_nonce}'\"],
|
|
859
|
+
'script-src': [\"'self'\", 'https://cdn.jsdelivr.net', 'https://apis.google.com', 'https://accounts.google.com', \"'nonce-#\{content_security_policy_nonce}'\"],
|
|
856
860
|
'connect-src': [\"'self'\", 'https://cdn.jsdelivr.net']
|
|
857
861
|
})
|
|
858
862
|
csp
|
|
859
863
|
end
|
|
860
864
|
end
|
|
861
865
|
end
|
|
862
|
-
end
|
|
863
|
-
|
|
864
|
-
|
|
866
|
+
end %>
|
|
867
|
+
<style>#{::Brick::Rails::BRICK_CSS}</style>
|
|
868
|
+
<script<%= @_request.env['_brick_nonce'] %>>
|
|
865
869
|
if (window.history.state && window.history.state.turbo)
|
|
866
870
|
window.addEventListener(\"popstate\", function () { location.reload(true); });
|
|
867
871
|
</script>
|
|
@@ -881,7 +885,11 @@ callbacks = {} %>"
|
|
|
881
885
|
poly_cols << @_brick_model.brick_foreign_type(v[1].first)
|
|
882
886
|
v.last[1].each_with_object([]) { |x, s| s << "[#{x.name}, #{x.primary_key.inspect}]" }.join(', ')
|
|
883
887
|
else
|
|
884
|
-
|
|
888
|
+
# If the BT association specifies a column for the primary_key, use that ...
|
|
889
|
+
fm_pk = @_brick_model.reflect_on_association(v.last.first)&.options&.[](:primary_key)&.to_s ||
|
|
890
|
+
# ... otherwise, use the model's primary_key.
|
|
891
|
+
(v.last[1].primary_key.present? && v.last[1].primary_key)
|
|
892
|
+
"[#{v.last[1].name}, #{fm_pk.inspect}]"
|
|
885
893
|
end
|
|
886
894
|
s << "#{v.first.inspect} => [#{v.last.first.inspect}, [#{foreign_models}], #{v.last[2].inspect}]"
|
|
887
895
|
end
|
|
@@ -973,19 +981,6 @@ if (window.brickFontFamily) {
|
|
|
973
981
|
}
|
|
974
982
|
var sheetUrl;
|
|
975
983
|
var spreadsheetId;
|
|
976
|
-
var sheetsLink = document.getElementById(\"sheetsLink\");
|
|
977
|
-
function gapiLoaded() {
|
|
978
|
-
// Have a click on the sheets link to bring up the sign-in window. (Must happen from some kind of user click.)
|
|
979
|
-
sheetsLink.addEventListener(\"click\", async function (evt) {
|
|
980
|
-
evt.preventDefault();
|
|
981
|
-
var client = google.accounts.oauth2.initTokenClient({
|
|
982
|
-
client_id: \"487319557829-fgj4u660igrpptdji7ev0r5hb6kh05dh.apps.googleusercontent.com\",
|
|
983
|
-
scope: \"https://www.googleapis.com/auth/spreadsheets https://www.googleapis.com/auth/drive.file\",
|
|
984
|
-
callback: updateSignInStatus
|
|
985
|
-
});
|
|
986
|
-
client.requestAccessToken();
|
|
987
|
-
});
|
|
988
|
-
}
|
|
989
984
|
|
|
990
985
|
async function updateSignInStatus(token) {
|
|
991
986
|
await new Promise(function (resolve) {
|
|
@@ -1044,7 +1039,24 @@ if (window.brickFontFamily) {
|
|
|
1044
1039
|
}
|
|
1045
1040
|
</script>
|
|
1046
1041
|
<script src=\"https://apis.google.com/js/api.js\"></script>
|
|
1047
|
-
<script async defer src=\"https://accounts.google.com/gsi/client\"
|
|
1042
|
+
<script async defer src=\"https://accounts.google.com/gsi/client\" id=\"gapiScript\"<%= @_request.env['_brick_nonce'] %>></script>
|
|
1043
|
+
<script<%= @_request.env['_brick_nonce'] %>>
|
|
1044
|
+
document.getElementById(\"gapiScript\").addEventListener(\"onload\",
|
|
1045
|
+
function () { // gapiLoaded
|
|
1046
|
+
var sheetsLink = document.getElementById(\"sheetsLink\");
|
|
1047
|
+
// Have a click on the sheets link to bring up the sign-in window. (Must happen from some kind of user click.)
|
|
1048
|
+
sheetsLink.addEventListener(\"click\", async function (evt) {
|
|
1049
|
+
evt.preventDefault();
|
|
1050
|
+
var client = google.accounts.oauth2.initTokenClient({
|
|
1051
|
+
client_id: \"487319557829-fgj4u660igrpptdji7ev0r5hb6kh05dh.apps.googleusercontent.com\",
|
|
1052
|
+
scope: \"https://www.googleapis.com/auth/spreadsheets https://www.googleapis.com/auth/drive.file\",
|
|
1053
|
+
callback: updateSignInStatus
|
|
1054
|
+
});
|
|
1055
|
+
client.requestAccessToken();
|
|
1056
|
+
});
|
|
1057
|
+
}
|
|
1058
|
+
);
|
|
1059
|
+
</script>
|
|
1048
1060
|
"
|
|
1049
1061
|
end # DutyFree data export and import
|
|
1050
1062
|
# %%% Instead of our current "for Janet Leverling (Employee)" kind of link we previously had this code that did a "where x = 123" thing:
|
|
@@ -1319,7 +1331,7 @@ end
|
|
|
1319
1331
|
kls = Object.const_get((rel = ::Brick.relations.fetch(r[0], nil))&.fetch(:class_name, nil))
|
|
1320
1332
|
rescue
|
|
1321
1333
|
end
|
|
1322
|
-
if kls.is_a?(Class) && (path_helper = respond_to?(bi_path = \"#\{kls._brick_index}_path\".to_sym) ? bi_path : nil)
|
|
1334
|
+
if kls.is_a?(Class) && kls.respond_to?(:_brick_index) && (path_helper = respond_to?(bi_path = \"#\{kls._brick_index}_path\".to_sym) ? bi_path : nil)
|
|
1323
1335
|
link_to(r[0], send(path_helper))
|
|
1324
1336
|
else
|
|
1325
1337
|
r[0]
|
|
@@ -1603,7 +1615,7 @@ flatpickr(\".timepicker\", {enableTime: true, noCalendar: true});
|
|
|
1603
1615
|
# Uncaught TypeError: Failed to resolve module specifier \"immutable-json-patch\". Relative references must start with either \"/\", \"./\", or \"../\".
|
|
1604
1616
|
if @_json_fields_present %>
|
|
1605
1617
|
<link rel=\"stylesheet\" type=\"text/css\" href=\"https://cdn.jsdelivr.net/npm/vanilla-jsoneditor@0.19.0/themes/jse-theme-default.min.css\">
|
|
1606
|
-
<script type=\"module\"
|
|
1618
|
+
<script type=\"module\"<%= @_request.env['_brick_nonce'] %>>
|
|
1607
1619
|
import { JSONEditor } from \"https://cdn.jsdelivr.net/npm/vanilla-jsoneditor@0.19.0/index.min.js\";
|
|
1608
1620
|
document.querySelectorAll(\"input.jsonpicker\").forEach(function (inp) {
|
|
1609
1621
|
var jsonDiv;
|
|
@@ -112,7 +112,7 @@ module Brick::Rails::FormTags
|
|
|
112
112
|
next unless klass.table_exists?
|
|
113
113
|
|
|
114
114
|
rid = pk.map { |pk_part| obj.send(pk_part.to_sym) }
|
|
115
|
-
out << "<tr x-id=\"#{rid.join('/')}\">\n"
|
|
115
|
+
out << "<tr x-id=\"#{slashed_rid = rid.join('/')}\">\n"
|
|
116
116
|
out << "<td class=\"col-sticky alternating-gray\">#{link_to('⇛', send("#{klass._brick_index(:singular)}_path".to_sym, rid),
|
|
117
117
|
{ class: 'big-arrow' })}</td>\n" if pk.present?
|
|
118
118
|
ac = obj.instance_variable_get(:@association_cache) || obj.instance_variable_set(:@association_cache, {})
|
|
@@ -134,8 +134,14 @@ module Brick::Rails::FormTags
|
|
|
134
134
|
if bt[2] && obj.respond_to?(poly_id_col = "#{bt.first}_id") # Polymorphic?
|
|
135
135
|
if (poly_id = obj.send(poly_id_col))
|
|
136
136
|
bt_class = obj.send(klass.brick_foreign_type(bt.first))
|
|
137
|
-
|
|
138
|
-
|
|
137
|
+
root_class_name = (::Brick.existing_stis[bt_class] || bt_class)
|
|
138
|
+
begin
|
|
139
|
+
base_class_underscored = root_class_name.constantize.base_class._brick_index(:singular)
|
|
140
|
+
out << link_to("#{bt_class} ##{poly_id}", send("#{base_class_underscored}_path".to_sym, poly_id))
|
|
141
|
+
rescue NameError => ee
|
|
142
|
+
puts "WARNING: While searching for a polymorphically associated #{bt.first} for the #{klass.name} with ID #{slashed_rid}, was unable to locate a model called \"#{root_class_name}\". This model might have been deleted, thereby orphaning rows in the #{klass.table_name} table."
|
|
143
|
+
out << "<span class=\"orphan\"><< Orphaned \"#{root_class_name}\" with ID: #{slashed_rid} >></span>"
|
|
144
|
+
end
|
|
139
145
|
end
|
|
140
146
|
else # BT or HOT
|
|
141
147
|
bt_class = bt[1].first.first
|
|
@@ -151,11 +157,17 @@ module Brick::Rails::FormTags
|
|
|
151
157
|
end
|
|
152
158
|
br_descrip_args = [obj]
|
|
153
159
|
br_descrip_args += [bt_class._brick_deserialized_value(obj, descrips[0..-2]), bt_id_col] if descrips
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
160
|
+
out << if bt_id_col.blank? && bt[1].first[1] # Is this a BT which references a table with no primary key?
|
|
161
|
+
# Although we have no way to directly reference this record via a show action, we can at least create a link like this:
|
|
162
|
+
# http://localhost:3000/brick/local_authority_postcode?__value=PA2Y+5LQ
|
|
163
|
+
link_to(val, send("#{bt_class.base_class._brick_index(:singular)}_path".to_sym, '__the_id__')).gsub('__the_id__', "?__#{bt[1].first[1]}=#{CGI.escape(val)}")
|
|
164
|
+
else # Normal BT or HOT
|
|
165
|
+
bt_txt = bt_class.brick_descrip(*br_descrip_args)
|
|
166
|
+
bt_txt = ::Brick::Rails.display_binary(bt_txt).html_safe if bt_txt&.encoding&.name == 'ASCII-8BIT'
|
|
167
|
+
bt_txt ||= "<span class=\"orphan\"><< Orphaned ID: #{val} >></span>" if val
|
|
168
|
+
bt_id = bt_class._brick_deserialized_id(obj, bt_id_col)
|
|
169
|
+
(bt_id&.first ? link_to(bt_txt, send("#{bt_class.base_class._brick_index(:singular)}_path".to_sym, bt_id)) : bt_txt || '')
|
|
170
|
+
end
|
|
159
171
|
end
|
|
160
172
|
elsif (hms_col = hms_cols[col_name])
|
|
161
173
|
if hms_col.length == 1
|
|
@@ -165,15 +177,14 @@ module Brick::Rails::FormTags
|
|
|
165
177
|
if col[2] == 'HO'
|
|
166
178
|
descrips = bt_descrip[col_name.to_sym][hm_klass]
|
|
167
179
|
if (descrip_parts = hm_klass._brick_deserialized_value(obj, descrips[0..-2]))&.first
|
|
180
|
+
ho_id = hm_klass._brick_deserialized_id(obj, ho_id_col = descrips.last)
|
|
168
181
|
ho_txt = if hm_klass.name == 'ActiveStorage::Attachment'
|
|
169
182
|
begin
|
|
170
183
|
::Brick::Rails.display_binary(obj.send(col[3])&.blob&.download)&.html_safe
|
|
171
184
|
rescue
|
|
185
|
+
# Attachment is missing for some reason ... default to showing just a description.
|
|
172
186
|
end
|
|
173
|
-
|
|
174
|
-
hm_klass.brick_descrip(obj, descrip_parts, ho_id_col = descrips.last)
|
|
175
|
-
end
|
|
176
|
-
ho_id = hm_klass._brick_deserialized_id(obj, ho_id_col)
|
|
187
|
+
end || hm_klass.brick_descrip(obj, descrip_parts, ho_id_col)
|
|
177
188
|
out << link_to(ho_txt, send("#{hm_klass.base_class._brick_index(:singular)}_path".to_sym, ho_id))
|
|
178
189
|
end
|
|
179
190
|
elsif obj.respond_to?(ct_col = hms_col[1].to_sym) && (ct = obj.send(ct_col)&.to_i)&.positive?
|
data/lib/brick/rails.rb
CHANGED
|
@@ -179,7 +179,7 @@ erDiagram
|
|
|
179
179
|
'timestamp without time zone' => 'timestamp',
|
|
180
180
|
'timestamp with time zone' => 'timestamp',
|
|
181
181
|
'time without time zone' => 'time',
|
|
182
|
-
'time with time zone' => 'time' }[dt] || dt&.tr(' (', '_')
|
|
182
|
+
'time with time zone' => 'time' }[dt] || dt&.tr(' (', '_')&.tr(')', '') || 'int'
|
|
183
183
|
end
|
|
184
184
|
callbacks.merge({#{model_short_name.inspect} => ::#{model.name}}).each do |cb_k, cb_class|
|
|
185
185
|
cb_relation = ::Brick.relations[cb_class.table_name]
|
data/lib/brick/reflect_tables.rb
CHANGED
|
@@ -425,8 +425,7 @@ ORDER BY 1, 2, c.internal_column_id, acc.position"
|
|
|
425
425
|
end
|
|
426
426
|
)&.present?
|
|
427
427
|
if tnp.last&.start_with?('::') # TNP that points to an exact class?
|
|
428
|
-
|
|
429
|
-
[singular]
|
|
428
|
+
tnp.last[2..-1].split('::')
|
|
430
429
|
elsif tnp.last
|
|
431
430
|
v[:auto_prefixed_schema], v[:auto_prefixed_class] = tnp
|
|
432
431
|
# v[:resource] = rel_name.last[tnp.first.length..-1]
|
data/lib/brick/version_number.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
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.246
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Lorin Thwaits
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: activerecord
|
|
@@ -246,7 +245,6 @@ homepage: https://github.com/lorint/brick
|
|
|
246
245
|
licenses:
|
|
247
246
|
- MIT
|
|
248
247
|
metadata: {}
|
|
249
|
-
post_install_message:
|
|
250
248
|
rdoc_options: []
|
|
251
249
|
require_paths:
|
|
252
250
|
- lib
|
|
@@ -261,8 +259,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
261
259
|
- !ruby/object:Gem::Version
|
|
262
260
|
version: 1.3.6
|
|
263
261
|
requirements: []
|
|
264
|
-
rubygems_version:
|
|
265
|
-
signing_key:
|
|
262
|
+
rubygems_version: 4.0.18
|
|
266
263
|
specification_version: 4
|
|
267
264
|
summary: Create a Rails app from data alone
|
|
268
265
|
test_files: []
|