brick 1.0.44 → 1.0.47
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 +35 -23
- data/lib/brick/frameworks/rails/engine.rb +47 -29
- data/lib/brick/version_number.rb +1 -1
- data/lib/brick.rb +6 -2
- 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: 4180c0164d7f086112339696df9d8fef2aeebcd32d9b81faf22d76ddc11815bc
|
4
|
+
data.tar.gz: 823673bcbecc342f5df15e196ee65ad6f6ac0b75415514079c055af06d0ac7f6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1d17b1abd64051066b71839095be1e672b897ad707a2d10f4ca4429131c894ee178711c873cef59957111704437b86b6322b8909ab5cc41cc955547146377dd8
|
7
|
+
data.tar.gz: e210becff69096e73b9b7fa09bb4e1be6c36cd2982305b2c803c9c00e9d2b5b085857ea6edacc62498557cde928e2afbbb42ebbd137180385ec3a8a0c5efdf85
|
data/lib/brick/extensions.rb
CHANGED
@@ -274,7 +274,6 @@ module ActiveRecord
|
|
274
274
|
table = table.left
|
275
275
|
end
|
276
276
|
(_brick_chains[table._arel_table_type] ||= []) << (alias_name || table.table_alias || table.name)
|
277
|
-
# puts "YES! #{self.object_id}"
|
278
277
|
end
|
279
278
|
# rubocop:enable Style/IdenticalConditionalBranches
|
280
279
|
when Arel::Table # Table
|
@@ -286,9 +285,9 @@ module ActiveRecord
|
|
286
285
|
# Spin up an empty set of Brick alias name chains at the start
|
287
286
|
@_brick_chains = {}
|
288
287
|
# The left side is the "FROM" table
|
289
|
-
# names += _recurse_arel(piece.left)
|
290
288
|
names << (this_name = [piece.left._arel_table_type, (piece.left.table_alias || piece.left.name)])
|
291
|
-
|
289
|
+
# # Do not currently need the root "FROM" table in our list of chains
|
290
|
+
# (_brick_chains[this_name.first] ||= []) << this_name.last
|
292
291
|
# The right side is an array of all JOINs
|
293
292
|
piece.right.each { |join| names << _recurse_arel(join) }
|
294
293
|
end
|
@@ -354,7 +353,6 @@ module ActiveRecord
|
|
354
353
|
next if bt[2] # Polymorphic?
|
355
354
|
|
356
355
|
# join_array will receive this relation name when calling #brick_parse_dsl
|
357
|
-
# binding.pry if bt.length > 2
|
358
356
|
bt_descrip[bt.first] = if bt[1].is_a?(Array)
|
359
357
|
bt[1].each_with_object({}) { |bt_class, s| s[bt_class] = bt_class.brick_parse_dsl(join_array, bt.first, translations, true) }
|
360
358
|
else
|
@@ -598,7 +596,7 @@ Module.class_exec do
|
|
598
596
|
# See if a file is there in the same way that ActiveSupport::Dependencies#load_missing_constant
|
599
597
|
# checks for it in ~/.rvm/gems/ruby-2.7.5/gems/activesupport-5.2.6.2/lib/active_support/dependencies.rb
|
600
598
|
|
601
|
-
if (base_model = ::Brick.config.sti_namespace_prefixes&.fetch("::#{name}::", nil)&.constantize) || # Are we part of an auto-STI namespace? ...
|
599
|
+
if (base_model = ::Brick.config.sti_namespace_prefixes&.fetch("::#{self.name}::", nil)&.constantize) || # Are we part of an auto-STI namespace? ...
|
602
600
|
self != Object # ... or otherwise already in some namespace?
|
603
601
|
schema_name = [(singular_schema_name = name.underscore),
|
604
602
|
(schema_name = singular_schema_name.pluralize),
|
@@ -775,33 +773,47 @@ class Object
|
|
775
773
|
end # class definition
|
776
774
|
# Having this separate -- will this now work out better?
|
777
775
|
built_model.class_exec do
|
778
|
-
hmts&.each do |hmt_fk,
|
776
|
+
hmts&.each do |hmt_fk, hms|
|
779
777
|
hmt_fk = hmt_fk.tr('.', '_')
|
780
|
-
|
781
|
-
# %%%
|
782
|
-
through = ::Brick.config.schema_behavior[:multitenant] ?
|
783
|
-
|
784
|
-
|
785
|
-
|
778
|
+
hms.each do |hm|
|
779
|
+
# %%% Need to confirm that HMTs work when they are built from has_manys with custom names
|
780
|
+
through = ::Brick.config.schema_behavior[:multitenant] ? hm.first[:assoc_name] : hm.first[:inverse_table].tr('.', '_').pluralize
|
781
|
+
options = {}
|
782
|
+
hmt_name = if hms.length > 1
|
783
|
+
if hms[0].first[:inverse][:assoc_name] == hms[1].first[:inverse][:assoc_name] # Same BT names pointing back to us? (Most common scenario)
|
784
|
+
"#{hmt_fk}_through_#{hm.first[:assoc_name]}"
|
786
785
|
else # Use BT names to provide uniqueness
|
787
|
-
|
788
|
-
|
786
|
+
if self.name.underscore.singularize == hm.first[:alternate_name]
|
787
|
+
# Has previously been:
|
788
|
+
# # If it folds back on itself then look at the other side
|
789
|
+
# # (At this point just infer the source be the inverse of the first has_many that
|
790
|
+
# # we find that is not ourselves. If there are more than two then uh oh, can't
|
791
|
+
# # yet handle that rare circumstance!)
|
792
|
+
# other = hms.find { |hm1| hm1 != hm } # .first[:fk]
|
793
|
+
# options[:source] = other.first[:inverse][:assoc_name].to_sym
|
794
|
+
# And also has been:
|
795
|
+
# hm.first[:inverse][:assoc_name].to_sym
|
796
|
+
options[:source] = hm.last.to_sym
|
797
|
+
else
|
798
|
+
through = hm.first[:alternate_name].pluralize
|
799
|
+
end
|
800
|
+
singular_assoc_name = hm.first[:inverse][:assoc_name].singularize
|
789
801
|
"#{singular_assoc_name}_#{hmt_fk}"
|
790
802
|
end
|
791
803
|
else
|
792
804
|
hmt_fk
|
793
805
|
end
|
794
|
-
options =
|
806
|
+
options[:through] = through.to_sym
|
795
807
|
if relation[:fks].any? { |k, v| v[:assoc_name] == hmt_name }
|
796
|
-
hmt_name = "#{hmt_name.singularize}_#{
|
808
|
+
hmt_name = "#{hmt_name.singularize}_#{hm.first[:assoc_name]}"
|
797
809
|
# Was:
|
798
|
-
# options[:class_name] =
|
799
|
-
# options[:foreign_key] =
|
800
|
-
far_assoc = relations[
|
810
|
+
# options[:class_name] = hm.first[:inverse_table].singularize.camelize
|
811
|
+
# options[:foreign_key] = hm.first[:fk].to_sym
|
812
|
+
far_assoc = relations[hm.first[:inverse_table]][:fks].find { |_k, v| v[:assoc_name] == hm.last }
|
801
813
|
options[:class_name] = far_assoc.last[:inverse_table].singularize.camelize
|
802
814
|
options[:foreign_key] = far_assoc.last[:fk].to_sym
|
803
815
|
end
|
804
|
-
options[:source]
|
816
|
+
options[:source] ||= hm.last.to_sym unless hmt_name.singularize == hm.last
|
805
817
|
code << " has_many :#{hmt_name}#{options.map { |opt| ", #{opt.first}: #{opt.last.inspect}" }.join}\n"
|
806
818
|
self.send(:has_many, hmt_name.to_sym, **options)
|
807
819
|
end
|
@@ -832,13 +844,13 @@ class Object
|
|
832
844
|
need_fk = "#{assoc_name}_id" != assoc[:fk]
|
833
845
|
end
|
834
846
|
if (inverse = assoc[:inverse])
|
835
|
-
inverse_assoc_name, _x = _brick_get_hm_assoc_name(relations[inverse_table], inverse)
|
836
847
|
# If it's multitenant with something like: public.____ ...
|
837
848
|
if (it_parts = inverse_table.split('.')).length > 1 &&
|
838
849
|
::Brick.config.schema_behavior[:multitenant] && Object.const_defined?('Apartment') &&
|
839
850
|
it_parts.first == Apartment.default_schema
|
840
851
|
it_parts.shift # ... then ditch the generic schema name
|
841
852
|
end
|
853
|
+
inverse_assoc_name, _x = _brick_get_hm_assoc_name(relations[inverse_table], inverse, it_parts.join('_').singularize)
|
842
854
|
has_ones = ::Brick.config.has_ones&.fetch(it_parts.join('/').singularize.camelize, nil)
|
843
855
|
if has_ones&.key?(singular_inv_assoc_name = ActiveSupport::Inflector.singularize(inverse_assoc_name.tr('.', '_')))
|
844
856
|
inverse_assoc_name = if has_ones[singular_inv_assoc_name]
|
@@ -1086,9 +1098,9 @@ class Object
|
|
1086
1098
|
[built_controller, code]
|
1087
1099
|
end
|
1088
1100
|
|
1089
|
-
def _brick_get_hm_assoc_name(relation, hm_assoc)
|
1101
|
+
def _brick_get_hm_assoc_name(relation, hm_assoc, source = nil)
|
1090
1102
|
if (relation[:hm_counts][hm_assoc[:assoc_name]]&.> 1) &&
|
1091
|
-
hm_assoc[:alternate_name] !=
|
1103
|
+
hm_assoc[:alternate_name] != (source || name.underscore)
|
1092
1104
|
plural = ActiveSupport::Inflector.pluralize(hm_assoc[:alternate_name])
|
1093
1105
|
new_alt_name = (hm_assoc[:alternate_name] == name.underscore) ? "#{hm_assoc[:assoc_name].singularize}_#{plural}" : plural
|
1094
1106
|
# uniq = 1
|
@@ -105,13 +105,26 @@ module Brick
|
|
105
105
|
hms_columns = [] # Used for 'index'
|
106
106
|
skip_klass_hms = ::Brick.config.skip_index_hms[model_name] || {}
|
107
107
|
hms_headers = hms.each_with_object([]) do |hm, s|
|
108
|
-
hm_stuff = [(hm_assoc = hm.last),
|
108
|
+
hm_stuff = [(hm_assoc = hm.last),
|
109
|
+
"H#{hm_assoc.macro == :has_one ? 'O' : 'M'}#{'T' if hm_assoc.options[:through]}",
|
110
|
+
(assoc_name = hm.first)]
|
109
111
|
hm_fk_name = if hm_assoc.options[:through]
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
112
|
+
associative = associatives[hm.first]
|
113
|
+
tbl_nm = if hm_assoc.options[:source]
|
114
|
+
associative.klass.reflect_on_association(hm_assoc.options[:source]).inverse_of&.name
|
115
|
+
else
|
116
|
+
associative.name
|
117
|
+
end
|
118
|
+
# If there is no inverse available for the source belongs_to association, make one based on the class name
|
119
|
+
unless tbl_nm
|
120
|
+
tbl_nm = associative.class_name.underscore
|
121
|
+
tbl_nm.slice!(0) if tbl_nm[0] == ('/')
|
122
|
+
tbl_nm = tbl_nm.tr('/', '_').pluralize
|
123
|
+
end
|
124
|
+
"'#{tbl_nm}.#{associative.foreign_key}'"
|
125
|
+
else
|
126
|
+
hm_assoc.foreign_key
|
127
|
+
end
|
115
128
|
case args.first
|
116
129
|
when 'index'
|
117
130
|
hms_columns << if hm_assoc.macro == :has_many
|
@@ -168,10 +181,10 @@ module Brick
|
|
168
181
|
}
|
169
182
|
|
170
183
|
#headerTop {
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
184
|
+
position: sticky;
|
185
|
+
top: 0px;
|
186
|
+
background-color: white;
|
187
|
+
z-index: 1;
|
175
188
|
}
|
176
189
|
table {
|
177
190
|
border-collapse: collapse;
|
@@ -218,9 +231,6 @@ table tbody tr.active-row {
|
|
218
231
|
color: #009879;
|
219
232
|
}
|
220
233
|
|
221
|
-
td.val {
|
222
|
-
display: block;
|
223
|
-
}
|
224
234
|
a.show-arrow {
|
225
235
|
font-size: 1.5em;
|
226
236
|
text-decoration: none;
|
@@ -240,6 +250,10 @@ a.big-arrow {
|
|
240
250
|
.dimmed {
|
241
251
|
background-color: #C0C0C0;
|
242
252
|
}
|
253
|
+
.orphan {
|
254
|
+
color: red;
|
255
|
+
white-space: nowrap;
|
256
|
+
}
|
243
257
|
|
244
258
|
#revertTemplate {
|
245
259
|
display: none;
|
@@ -255,13 +269,13 @@ input+svg.revert {
|
|
255
269
|
top: 0.5em;
|
256
270
|
}
|
257
271
|
|
258
|
-
|
272
|
+
.update {
|
273
|
+
position: sticky;
|
274
|
+
right: 1em;
|
275
|
+
float: right;
|
259
276
|
background-color: #004998;
|
260
277
|
color: #FFF;
|
261
278
|
}
|
262
|
-
.right {
|
263
|
-
text-align: right;
|
264
|
-
}
|
265
279
|
</style>
|
266
280
|
<% is_includes_dates = nil
|
267
281
|
|
@@ -580,8 +594,8 @@ if (headerTop) {
|
|
580
594
|
# 0..62 because Postgres column names are limited to 63 characters
|
581
595
|
#{obj_name}, (descrips = @_brick_bt_descrip[bt.first][bt_class])[0..-2].map { |id| #{obj_name}.send(id.last[0..62]) }, (bt_id_col = descrips.last)
|
582
596
|
)
|
583
|
-
bt_txt ||= \"
|
584
|
-
bt_id = bt_id_col.map { |id_col| #{obj_name}.send(id_col.to_sym) }
|
597
|
+
bt_txt ||= \"<span class=\\\"orphan\\\"><< Orphaned ID: #\{val} >></span>\".html_safe if val
|
598
|
+
bt_id = bt_id_col.map { |id_col| #{obj_name}.send(id_col.to_sym) } %>
|
585
599
|
<%= bt_id&.first ? link_to(bt_txt, send(\"#\{bt_class.base_class.name.underscore.tr('/', '_')\}_path\".to_sym, bt_id)) : bt_txt %>
|
586
600
|
<%#= Previously was: bt_obj = bt[1].first.first.find_by(bt[2] => val); link_to(bt_obj.brick_descrip, send(\"#\{bt[1].first.first.name.underscore\}_path\".to_sym, bt_obj.send(bt[1].first.first.primary_key.to_sym))) if bt_obj %>
|
587
601
|
<% end %>
|
@@ -680,7 +694,7 @@ end
|
|
680
694
|
<%= k %>
|
681
695
|
<% end %>
|
682
696
|
</th>
|
683
|
-
<td
|
697
|
+
<td>
|
684
698
|
<% dt_pickers = { datetime: 'datetimepicker', timestamp: 'datetimepicker', time: 'timepicker', date: 'datepicker' }
|
685
699
|
if bt
|
686
700
|
html_options = { prompt: \"Select #\{bt_name\}\" }
|
@@ -689,18 +703,21 @@ end
|
|
689
703
|
<%= if (bt_obj = bt_class&.find_by(bt_pair[1] => val))
|
690
704
|
link_to('⇛', send(\"#\{bt_class.base_class.name.underscore.tr('/', '_')\}_path\".to_sym, bt_obj.send(bt_class.primary_key.to_sym)), { class: 'show-arrow' })
|
691
705
|
elsif val
|
692
|
-
\"<span>Orphaned ID: #\{val}</span>\".html_safe
|
706
|
+
\"<span class=\\\"orphan\\\">Orphaned ID: #\{val}</span>\".html_safe
|
693
707
|
end %><svg class=\"revert\" width=\"1.5em\" viewBox=\"0 0 512 512\"><use xlink:href=\"#revertPath\" /></svg>
|
694
|
-
<% else
|
708
|
+
<% else
|
709
|
+
html_options = {}
|
710
|
+
html_options[:class] = 'dimmed' unless val
|
711
|
+
case (col_type = #{model_name}.column_for_attribute(k).type)
|
695
712
|
when :string, :text %>
|
696
713
|
<% if is_bcrypt?(val) # || .readonly? %>
|
697
714
|
<%= hide_bcrypt(val, 1000) %>
|
698
715
|
<% else %>
|
699
|
-
<div class=\"wide-input\"><%= f.text_field
|
716
|
+
<div class=\"wide-input\"><%= f.text_field(k.to_sym, html_options) %><svg class=\"revert\" width=\"1.5em\" viewBox=\"0 0 512 512\"><use xlink:href=\"#revertPath\" /></svg></div>
|
700
717
|
<% end %>
|
701
718
|
<% when :boolean %>
|
702
719
|
<%= f.check_box k.to_sym %><svg class=\"revert\" width=\"1.5em\" viewBox=\"0 0 512 512\"><use xlink:href=\"#revertPath\" /></svg>
|
703
|
-
<% when :integer, :decimal, :float
|
720
|
+
<% when :integer, :decimal, :float %>
|
704
721
|
<%= if col_type == :integer
|
705
722
|
f.text_field k.to_sym, { pattern: '\\d*', class: 'check-validity' }
|
706
723
|
else
|
@@ -710,10 +727,11 @@ end
|
|
710
727
|
is_includes_dates = true %>
|
711
728
|
<%= f.text_field k.to_sym, { class: dt_pickers[col_type] } %><svg class=\"revert\" width=\"1.5em\" viewBox=\"0 0 512 512\"><use xlink:href=\"#revertPath\" /></svg>
|
712
729
|
<% when :uuid %>
|
713
|
-
|
714
|
-
|
715
|
-
|
716
|
-
|
730
|
+
<%=
|
731
|
+
# Postgres naturally uses the +uuid_generate_v4()+ function from the uuid-ossp extension
|
732
|
+
# If it's not yet enabled then: enable_extension 'uuid-ossp'
|
733
|
+
# ActiveUUID gem created a new :uuid type
|
734
|
+
val %>
|
717
735
|
<% when :binary, :primary_key %>
|
718
736
|
<% end %>
|
719
737
|
<% end %>
|
@@ -721,7 +739,7 @@ end
|
|
721
739
|
</tr>
|
722
740
|
<% end
|
723
741
|
if has_fields %>
|
724
|
-
<tr><td colspan=\"2\"
|
742
|
+
<tr><td colspan=\"2\"><%= f.submit({ class: 'update' }) %></td></tr>
|
725
743
|
<% else %>
|
726
744
|
<tr><td colspan=\"2\">(No displayable fields)</td></tr>
|
727
745
|
<% end %>
|
data/lib/brick/version_number.rb
CHANGED
data/lib/brick.rb
CHANGED
@@ -168,8 +168,12 @@ module Brick
|
|
168
168
|
skip_hms = {}
|
169
169
|
associatives = hms.each_with_object({}) do |hmt, s|
|
170
170
|
if (through = hmt.last.options[:through])
|
171
|
-
skip_hms[through] = nil
|
172
|
-
|
171
|
+
skip_hms[through] = nil # if hms[through]
|
172
|
+
# binding.pry if !hms[through]
|
173
|
+
# End up with a hash of HMT names pointing to join-table associations
|
174
|
+
# Last part was: hmt.last.name
|
175
|
+
# Changed up because looking for: hms[:issue_issue_duplicates]
|
176
|
+
s[hmt.first] = hms[through] # || hms["#{(opt = hmt.last.options)[:through].to_s.singularize}_#{opt[:source].to_s.pluralize}".to_sym]
|
173
177
|
elsif hmt.last.inverse_of.nil?
|
174
178
|
puts "SKIPPING #{hmt.last.name.inspect}"
|
175
179
|
# %%% If we don't do this then below associative.name will find that associative is nil
|
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.47
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lorin Thwaits
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-07-
|
11
|
+
date: 2022-07-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|