brick 1.0.130 → 1.0.132
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 +39 -26
- data/lib/brick/frameworks/rails/engine.rb +21 -18
- data/lib/brick/frameworks/rails/form_tags.rb +12 -1
- data/lib/brick/version_number.rb +1 -1
- data/lib/brick.rb +22 -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: '08cc0b19ab0838b667534f4de64f3a7045bf395202a3602981a20ececdc91ab5'
|
4
|
+
data.tar.gz: 4b976489a05bb26c3702746700025c6bad3bb930fc129ae897bc9e1596a50901
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 580db611d4ab9e2bf7ab0ed62a90940b90a4818619a9a91788802f017845c0aef3c8da1b01ea8a6a87c8e1af8378dc5c0d030396ebebba05d101b46ca0bd4495
|
7
|
+
data.tar.gz: fe876de91852b7213fa4d35b378935c7f18e18ae09ff5058f0d34b32dcb3c802a15d1c2cc79f63f7b5eac4177b7bbbeae43603e55499447cfee9e1d3556f64fa
|
data/lib/brick/extensions.rb
CHANGED
@@ -670,6 +670,7 @@ module ActiveRecord
|
|
670
670
|
link_back = []
|
671
671
|
# Track polymorphic type field if necessary
|
672
672
|
if hm.source_reflection.options[:as]
|
673
|
+
# Might be able to simplify as: hm.source_reflection.type
|
673
674
|
poly_ft = [hm.source_reflection.inverse_of.foreign_type, hmt_assoc.source_reflection.class_name]
|
674
675
|
end
|
675
676
|
# link_back << hm.source_reflection.inverse_of.name
|
@@ -753,7 +754,8 @@ module ActiveRecord
|
|
753
754
|
|
754
755
|
pri_tbl = hm.active_record
|
755
756
|
pri_key = hm.options[:primary_key] || pri_tbl.primary_key
|
756
|
-
unless hm.
|
757
|
+
unless hm.active_record.column_names.include?(pri_key)
|
758
|
+
# %%% When this gets hit then if an attempt is made to display the ERD, it might end up being blank
|
757
759
|
nix << k
|
758
760
|
next
|
759
761
|
end
|
@@ -874,6 +876,12 @@ JOIN (SELECT #{hm_selects.map { |s| "#{'br_t0.' if from_clause}#{s}" }.join(', '
|
|
874
876
|
def brick_list
|
875
877
|
pks = klass.primary_key.is_a?(String) ? [klass.primary_key] : klass.primary_key
|
876
878
|
selects = pks.each_with_object([]) { |pk, s| s << pk unless s.include?(pk) }
|
879
|
+
# Get foreign keys for anything marked to be auto-preloaded, or a self-referencing JOIN
|
880
|
+
klass_cols = klass.column_names
|
881
|
+
reflect_on_all_associations.each do |a|
|
882
|
+
selects << a.foreign_key if a.belongs_to? && (preload_values.include?(a.name) ||
|
883
|
+
(!a.options[:polymorphic] && a.klass == klass && klass_cols.include?(a.foreign_key)))
|
884
|
+
end
|
877
885
|
# ActiveStorage compatibility
|
878
886
|
selects << 'service_name' if klass.name == 'ActiveStorage::Blob' && ActiveStorage::Blob.columns_hash.key?('service_name')
|
879
887
|
selects << 'blob_id' if klass.name == 'ActiveStorage::Attachment' && ActiveStorage::Attachment.columns_hash.key?('blob_id')
|
@@ -1013,16 +1021,17 @@ Module.class_exec do
|
|
1013
1021
|
is_controller = requested.end_with?('Controller')
|
1014
1022
|
# self.name is nil when a model name is requested in an .erb file
|
1015
1023
|
if self.name && ::Brick.config.path_prefix
|
1016
|
-
|
1024
|
+
split_self_name.shift if (split_self_name = self.name.split('::')).first.blank?
|
1017
1025
|
# Asking for the prefix module?
|
1026
|
+
camelize_prefix = ::Brick.config.path_prefix.camelize
|
1018
1027
|
if self == Object && requested == camelize_prefix
|
1019
1028
|
Object.const_set(args.first, (built_module = Module.new))
|
1020
1029
|
puts "module #{camelize_prefix}; end\n"
|
1021
1030
|
return built_module
|
1022
|
-
|
1023
|
-
|
1024
|
-
if split_self_name.first == camelize_prefix
|
1031
|
+
elsif module_parent == Object && self.name == camelize_prefix ||
|
1032
|
+
module_parent.name == camelize_prefix && module_parent.module_parent == Object
|
1025
1033
|
split_self_name.shift # Remove the identified path prefix from the split name
|
1034
|
+
is_brick_prefix = true
|
1026
1035
|
if is_controller
|
1027
1036
|
brick_root = split_self_name.empty? ? self : camelize_prefix.constantize
|
1028
1037
|
end
|
@@ -1055,26 +1064,30 @@ Module.class_exec do
|
|
1055
1064
|
self
|
1056
1065
|
end
|
1057
1066
|
# puts "#{self.name} - #{args.first}"
|
1058
|
-
|
1059
|
-
|
1060
|
-
|
1061
|
-
|
1062
|
-
|
1063
|
-
|
1064
|
-
|
1065
|
-
|
1066
|
-
|
1067
|
-
|
1068
|
-
|
1069
|
-
|
1070
|
-
|
1071
|
-
|
1072
|
-
|
1073
|
-
|
1074
|
-
|
1075
|
-
|
1076
|
-
|
1077
|
-
|
1067
|
+
# Unless it's a Brick prefix looking for a TNP that should create a module ...
|
1068
|
+
unless (is_tnp_module = (is_brick_prefix && !is_controller && ::Brick.config.table_name_prefixes.values.include?(requested)))
|
1069
|
+
# ... first look around for an existing module or class.
|
1070
|
+
desired_classname = (self == Object || !name) ? requested : "#{name}::#{requested}"
|
1071
|
+
if ((is_defined = self.const_defined?(args.first)) && (possible = self.const_get(args.first)) &&
|
1072
|
+
# Reset `possible` if it's a controller request that's not a perfect match
|
1073
|
+
# Was: (possible = nil) but changed to #local_variable_set in order to suppress the "= should be ==" warning
|
1074
|
+
(possible&.name == desired_classname || (is_controller && binding.local_variable_set(:possible, nil)))) ||
|
1075
|
+
# Try to require the respective Ruby file
|
1076
|
+
((filename = ActiveSupport::Dependencies.search_for_file(desired_classname.underscore) ||
|
1077
|
+
(self != Object && ActiveSupport::Dependencies.search_for_file((desired_classname = requested).underscore))
|
1078
|
+
) && (require_dependency(filename) || true) &&
|
1079
|
+
((possible = self.const_get(args.first)) && possible.name == desired_classname)
|
1080
|
+
) ||
|
1081
|
+
# If any class has turned up so far (and we're not in the middle of eager loading)
|
1082
|
+
# then return what we've found.
|
1083
|
+
(is_defined && !::Brick.is_eager_loading) # Used to also have: && possible != self
|
1084
|
+
if ((!brick_root && (filename || possible.instance_of?(Class))) ||
|
1085
|
+
(possible.instance_of?(Module) && possible&.module_parent == self) ||
|
1086
|
+
(possible.instance_of?(Class) && possible == self)) && # Are we simply searching for ourselves?
|
1087
|
+
# Skip when what we found as `possible` is not related to the base class of an STI model
|
1088
|
+
(!sti_base || possible.is_a?(sti_base))
|
1089
|
+
return possible
|
1090
|
+
end
|
1078
1091
|
end
|
1079
1092
|
end
|
1080
1093
|
class_name = ::Brick.namify(requested)
|
@@ -1109,7 +1122,7 @@ Module.class_exec do
|
|
1109
1122
|
(plural_class_name = class_name.pluralize)].find { |s| Brick.db_schemas&.include?(s) }&.camelize ||
|
1110
1123
|
(::Brick.config.sti_namespace_prefixes&.key?("::#{class_name}::") && class_name) ||
|
1111
1124
|
(::Brick.config.table_name_prefixes.values.include?(class_name) && class_name))
|
1112
|
-
return self.const_get(schema_name) if self.const_defined?(schema_name)
|
1125
|
+
return self.const_get(schema_name) if !is_tnp_module && self.const_defined?(schema_name)
|
1113
1126
|
|
1114
1127
|
# Build out a module for the schema if it's namespaced
|
1115
1128
|
# schema_name = schema_name.camelize
|
@@ -3,7 +3,7 @@
|
|
3
3
|
module Brick
|
4
4
|
module Rails
|
5
5
|
class << self
|
6
|
-
def display_value(col_type, val)
|
6
|
+
def display_value(col_type, val, lat_lng = nil)
|
7
7
|
is_mssql_geography = nil
|
8
8
|
# Some binary thing that really looks like a Microsoft-encoded WGS84 point? (With the first two bytes, E6 10, indicating an EPSG code of 4326)
|
9
9
|
if col_type == :binary && val && val.length < 31 && (val.length - 6) % 8 == 0 && val[0..5].bytes == [230, 16, 0, 0, 1, 12]
|
@@ -61,14 +61,19 @@ module Brick
|
|
61
61
|
::Brick::Rails.display_binary(val)
|
62
62
|
else
|
63
63
|
if col_type
|
64
|
-
|
64
|
+
if lat_lng
|
65
|
+
# Create a link to this style of Google maps URL: https://www.google.com/maps/place/38.7071296+-121.2810649/@38.7071296,-121.2810649,12z
|
66
|
+
"<a href=\"https://www.google.com/maps/place/#{lat_lng.first}+#{lat_lng.last}/@#{lat_lng.first},#{lat_lng.last},12z\" target=\"blank\">#{val}</a>"
|
67
|
+
else
|
68
|
+
::Brick::Rails::FormBuilder.hide_bcrypt(val, col_type == :xml)
|
69
|
+
end
|
65
70
|
else
|
66
71
|
'?'
|
67
72
|
end
|
68
73
|
end
|
69
74
|
end
|
70
75
|
|
71
|
-
def display_binary(val)
|
76
|
+
def display_binary(val, max_size = 100_000)
|
72
77
|
return unless val
|
73
78
|
|
74
79
|
@image_signatures ||= { (+"\xFF\xD8\xFF\xEE").force_encoding('ASCII-8BIT') => 'jpeg',
|
@@ -94,15 +99,12 @@ module Brick
|
|
94
99
|
val = val[object_start...object_start + real_object_size]
|
95
100
|
end
|
96
101
|
|
97
|
-
if (signature = @image_signatures.find { |k, _v| val[0...k.length] == k }) ||
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
else
|
102
|
-
"< #{signature.last} image, #{val.length} bytes >"
|
103
|
-
end
|
102
|
+
if ((signature = @image_signatures.find { |k, _v| val[0...k.length] == k }&.last) ||
|
103
|
+
(val[0..3] == 'RIFF' && val[8..11] == 'WEBP' && binding.local_variable_set(:signature, 'webp'))) &&
|
104
|
+
val.length < max_size
|
105
|
+
"<img src=\"data:image/#{signature.last};base64,#{Base64.encode64(val)}\">"
|
104
106
|
else
|
105
|
-
"< 
|
107
|
+
"< #{signature ? "#{signature} image" : 'Binary'}, #{val.length} bytes >"
|
106
108
|
end
|
107
109
|
end
|
108
110
|
end
|
@@ -225,7 +227,7 @@ function linkSchemas() {
|
|
225
227
|
end
|
226
228
|
|
227
229
|
# When table names have specific prefixes, automatically place them in their own module with a table_name_prefix.
|
228
|
-
::Brick.table_name_prefixes
|
230
|
+
::Brick.config.table_name_prefixes ||= app.config.brick.fetch(:table_name_prefixes, {})
|
229
231
|
|
230
232
|
# Columns to treat as being metadata for purposes of identifying associative tables for has_many :through
|
231
233
|
::Brick.metadata_columns = app.config.brick.fetch(:metadata_columns, ['created_at', 'updated_at', 'deleted_at'])
|
@@ -625,6 +627,7 @@ window.addEventListener(\"popstate\", linkSchemas);
|
|
625
627
|
if (class_name = (resource_parts = resource_name.split('/')).last&.singularize)
|
626
628
|
resource_parts[-1] = class_name # Make sure the last part, defining the class name, is singular
|
627
629
|
begin
|
630
|
+
resource_parts.shift if resource_parts.first == ::Brick.config.path_prefix
|
628
631
|
if (model = Object.const_get(resource_parts.map(&:camelize).join('::')))&.is_a?(Class) && (
|
629
632
|
['index', 'show'].include?(find_args.first) || # Everything has index and show
|
630
633
|
# Only CUD stuff has create / update / destroy
|
@@ -1635,10 +1638,10 @@ end
|
|
1635
1638
|
<tr><td colspan=\"2\">(No displayable fields)</td></tr>
|
1636
1639
|
<% end %>
|
1637
1640
|
</table>#{
|
1638
|
-
"<%=
|
1639
|
-
|
1640
|
-
|
1641
|
-
|
1641
|
+
"<%= begin
|
1642
|
+
::Brick::Rails.display_binary(obj&.blob&.download, 500_000)&.html_safe
|
1643
|
+
rescue
|
1644
|
+
end %>" if model_name == 'ActiveStorage::Attachment'}
|
1642
1645
|
<% end %>
|
1643
1646
|
|
1644
1647
|
#{unless args.first == 'new'
|
@@ -1669,11 +1672,11 @@ end
|
|
1669
1672
|
<% if (assoc = @#{obj_name}.class.reflect_on_association(:#{hm_name})).macro == :has_one &&
|
1670
1673
|
assoc.options&.fetch(:through, nil).nil?
|
1671
1674
|
# In order to apply DSL properly, evaluate this HO the other way around as if it were as a BT
|
1672
|
-
collection = assoc.klass.where(assoc.foreign_key => @#{obj_name}.#{pk})
|
1675
|
+
collection = assoc.klass.where(assoc.foreign_key => #{pk.is_a?(String) ? "@#{obj_name}.#{pk}" : pk.map { |pk_part| "@#{obj_name}.#{pk_part}" }.inspect})
|
1673
1676
|
collection = collection.instance_exec(&assoc.scopes.first) if assoc.scopes.present?
|
1674
1677
|
if assoc.klass.name == 'ActiveStorage::Attachment'
|
1675
1678
|
br_descrip = begin
|
1676
|
-
::Brick::Rails.display_binary(obj.send(assoc.name)&.blob&.download)&.html_safe
|
1679
|
+
::Brick::Rails.display_binary(obj.send(assoc.name)&.blob&.download, 500_000)&.html_safe
|
1677
1680
|
rescue
|
1678
1681
|
end
|
1679
1682
|
end
|
@@ -139,8 +139,19 @@ module Brick::Rails::FormTags
|
|
139
139
|
out << if @_brick_monetized_attributes&.include?(col_name)
|
140
140
|
val ? Money.new(val.to_i).format : ''
|
141
141
|
else
|
142
|
+
lat_lng = if [:float, :decimal].include?(col.type) &&
|
143
|
+
(
|
144
|
+
((col_name == 'latitude' && obj.respond_to?('longitude') && (lng = obj.send('longitude')) && lng.is_a?(Numeric) && (lat = val)) ||
|
145
|
+
(col_name == 'longitude' && obj.respond_to?('latitude') && (lat = obj.send('latitude')) && lat.is_a?(Numeric) && (lng = val))
|
146
|
+
) ||
|
147
|
+
((col_name == 'lat' && obj.respond_to?('lng') && (lng = obj.send('lng')) && lng.is_a?(Numeric) && (lat = val)) ||
|
148
|
+
(col_name == 'lng' && obj.respond_to?('lat') && (lat = obj.send('lat')) && lat.is_a?(Numeric) && (lng = val))
|
149
|
+
)
|
150
|
+
)
|
151
|
+
[lat, lng]
|
152
|
+
end
|
142
153
|
col_type = col&.sql_type == 'geography' ? col.sql_type : col&.type
|
143
|
-
::Brick::Rails.display_value(col_type || col&.sql_type, val).to_s
|
154
|
+
::Brick::Rails.display_value(col_type || col&.sql_type, val, lat_lng).to_s
|
144
155
|
end
|
145
156
|
elsif cust_col
|
146
157
|
data = cust_col.first.map { |cc_part| obj.send(cc_part.last) }
|
data/lib/brick/version_number.rb
CHANGED
data/lib/brick.rb
CHANGED
@@ -125,6 +125,7 @@ if Gem::Specification.all_names.any? { |g| g.start_with?('rails-') }
|
|
125
125
|
end
|
126
126
|
module Brick
|
127
127
|
ALL_API_ACTIONS = [:index, :show, :create, :update, :destroy]
|
128
|
+
CURRENCY_SYMBOLS = '$£¢₵€₠ƒ¥₿₩₪₹₫₴₱₲₳₸₺₼₽៛₡₢₣₤₥₦₧₨₭₮₯₰₶₷₻₾'
|
128
129
|
|
129
130
|
class << self
|
130
131
|
def sti_models
|
@@ -200,9 +201,20 @@ module Brick
|
|
200
201
|
end
|
201
202
|
|
202
203
|
def get_bts_and_hms(model)
|
204
|
+
model_cols = model.columns_hash
|
205
|
+
pk_type = if (mpk = model.primary_key).is_a?(Array)
|
206
|
+
# Composite keys should really use: model.primary_key.map { |pk_part| model_cols[pk_part].type }
|
207
|
+
model_cols[mpk.first].type
|
208
|
+
else
|
209
|
+
mpk && model_cols[mpk].type
|
210
|
+
end
|
203
211
|
bts, hms = model.reflect_on_all_associations.each_with_object([{}, {}]) do |a, s|
|
212
|
+
# %%% The time will come when we will support type checking of composite foreign keys!
|
213
|
+
# binding.pry if a.foreign_key.is_a?(Array)
|
204
214
|
next unless a.polymorphic? || (!a.belongs_to? && (through = a.options[:through])) ||
|
205
|
-
(a.klass && ::Brick.config.exclude_tables.exclude?(a.klass.table_name)
|
215
|
+
(a.klass && ::Brick.config.exclude_tables.exclude?(a.klass.table_name) &&
|
216
|
+
(!a.belongs_to? || model_cols[a.foreign_key]&.type == pk_type)
|
217
|
+
)
|
206
218
|
|
207
219
|
if a.belongs_to?
|
208
220
|
if a.polymorphic?
|
@@ -239,6 +251,15 @@ module Brick
|
|
239
251
|
puts "WARNING: HMT relationship :#{a.name} in model #{model.name} has invalid source :#{a.source_reflection_name}."
|
240
252
|
next
|
241
253
|
end
|
254
|
+
else
|
255
|
+
if !a.options.key?(:as) && a.klass.column_names.exclude?(a.foreign_key)
|
256
|
+
options = ", #{a.options.map { |k, v| "#{k.inspect} => #{v.inspect}" }.join(', ')}" if a.options.present?
|
257
|
+
puts "WARNING: Model #{model.name} has this association:
|
258
|
+
has_many :#{a.name}#{options}
|
259
|
+
which expects column #{a.foreign_key} to exist in table #{a.klass.table_name}. This column is missing."
|
260
|
+
next
|
261
|
+
|
262
|
+
end
|
242
263
|
end
|
243
264
|
s.last[a.name] = a
|
244
265
|
end
|
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.132
|
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-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|