brick 1.0.43 → 1.0.46

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: 8387796a98b0bcf24586c6b31f091cfdc4cca1b45b73d02de3bdba17430625f7
4
- data.tar.gz: 1c7509e21a1a9a6c8c52f3015b0a7e34222ff944433e028be314f8525ee948b8
3
+ metadata.gz: 1442fb46672a819689a1f15aa16e2dd53647a057ea38948431746d3d8baf66f0
4
+ data.tar.gz: 38d26e09e226d37e87737cba35f76ee3b2413dc4474ac8ecba582297205789aa
5
5
  SHA512:
6
- metadata.gz: 75222971d2407d8ffb3b8412694da3fe6ad0d3f27f147159f6d75aa712d1dfe8a9d54627cb2c816fdfc8cb7c44de4407f180fbc559b9c811719c22a016c913f5
7
- data.tar.gz: 44e03a9d2ddec85969d5b1aca67a9426a4b3dd33f196c058d57b380fa77e78424768dd3e97a40227b2372bec4ccd81dfd1b7760b65e2c5b292c8b47c0d27e2c7
6
+ metadata.gz: 8cb9e747cffb1e33f045f07656891b8e17ac4349661f897aa01886bae6fb7c2e4687f1021e04173266ab60cf330ec71f58514aeb670669f30ea8c6dd4140e943
7
+ data.tar.gz: 54166ef84adaeab00c2d6408e9a9a6c5da5998bd278b0db490943d2d8da2701938cdc87a4c40ff65ac2cbe7196a7eb014a4b3b08dfd2ff5aa2ec426af00d38ab
@@ -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
- (_brick_chains[this_name.first] ||= []) << this_name.last
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
@@ -364,7 +363,12 @@ module ActiveRecord
364
363
  hms.each do |k, hm|
365
364
  next if skip_klass_hms.key?(k)
366
365
 
367
- hm_counts[k] = hm
366
+ if hm.macro == :has_one
367
+ # For our purposes a :has_one is similar enough to a :belongs_to that we can just join forces
368
+ bt_descrip[k] = { hm.klass => hm.klass.brick_parse_dsl(join_array, k, translations) }
369
+ else # Standard :has_many
370
+ hm_counts[k] = hm
371
+ end
368
372
  end
369
373
  end
370
374
 
@@ -650,10 +654,11 @@ class Object
650
654
  private
651
655
 
652
656
  def build_model(schema_name, inheritable_name, model_name, singular_table_name, table_name, relations, matching)
653
- full_name = if (::Brick.config.schema_behavior[:multitenant] && Object.const_defined?('Apartment') && schema_name == Apartment.default_schema)
654
- relation = relations["#{schema_name}.#{matching}"]
655
- inheritable_name || model_name
656
- elsif schema_name.blank?
657
+ if ::Brick.config.schema_behavior[:multitenant] && Object.const_defined?('Apartment') &&
658
+ schema_name == Apartment.default_schema
659
+ relation = relations["#{schema_name}.#{matching}"]
660
+ end
661
+ full_name = if relation || schema_name.blank?
657
662
  inheritable_name || model_name
658
663
  else # Prefix the schema to the table name + prefix the schema namespace to the class name
659
664
  schema_module = if schema_name.instance_of?(Module) # from an auto-STI namespace?
@@ -749,10 +754,10 @@ class Object
749
754
  if assoc[:is_bt]
750
755
  invs = invs.first # Just do the first one of what would be multiple identical polymorphic belongs_to
751
756
  else
752
- invs.each { |inv| build_bt_or_hm(relations, model_name, relation, hmts, assoc, inverse_assoc_name, inv, code) }
757
+ invs.each { |inv| build_bt_or_hm(full_name, relations, relation, hmts, assoc, inverse_assoc_name, inv, code) }
753
758
  end
754
759
  end
755
- build_bt_or_hm(relations, model_name, relation, hmts, assoc, inverse_assoc_name, invs, code) unless invs.is_a?(Array)
760
+ build_bt_or_hm(full_name, relations, relation, hmts, assoc, inverse_assoc_name, invs, code) unless invs.is_a?(Array)
756
761
  hmts
757
762
  end
758
763
  # # Not NULLables
@@ -804,7 +809,7 @@ class Object
804
809
  [built_model, code]
805
810
  end
806
811
 
807
- def build_bt_or_hm(relations, model_name, relation, hmts, assoc, inverse_assoc_name, inverse_table, code)
812
+ def build_bt_or_hm(full_name, relations, relation, hmts, assoc, inverse_assoc_name, inverse_table, code)
808
813
  singular_table_name = inverse_table&.singularize
809
814
  options = {}
810
815
  macro = if assoc[:is_bt]
@@ -825,9 +830,15 @@ class Object
825
830
  need_fk = "#{assoc_name}_id" != assoc[:fk]
826
831
  end
827
832
  if (inverse = assoc[:inverse])
828
- inverse_assoc_name, _x = _brick_get_hm_assoc_name(relations[inverse_table], inverse)
829
- has_ones = ::Brick.config.has_ones&.fetch(inverse[:alternate_name].camelize, nil)
830
- if has_ones&.key?(singular_inv_assoc_name = ActiveSupport::Inflector.singularize(inverse_assoc_name))
833
+ # If it's multitenant with something like: public.____ ...
834
+ if (it_parts = inverse_table.split('.')).length > 1 &&
835
+ ::Brick.config.schema_behavior[:multitenant] && Object.const_defined?('Apartment') &&
836
+ it_parts.first == Apartment.default_schema
837
+ it_parts.shift # ... then ditch the generic schema name
838
+ end
839
+ inverse_assoc_name, _x = _brick_get_hm_assoc_name(relations[inverse_table], inverse, it_parts.join('_').singularize)
840
+ has_ones = ::Brick.config.has_ones&.fetch(it_parts.join('/').singularize.camelize, nil)
841
+ if has_ones&.key?(singular_inv_assoc_name = ActiveSupport::Inflector.singularize(inverse_assoc_name.tr('.', '_')))
831
842
  inverse_assoc_name = if has_ones[singular_inv_assoc_name]
832
843
  need_inverse_of = true
833
844
  has_ones[singular_inv_assoc_name]
@@ -838,7 +849,6 @@ class Object
838
849
  end
839
850
  :belongs_to
840
851
  else
841
- # need_class_name = ActiveSupport::Inflector.singularize(assoc_name) == ActiveSupport::Inflector.singularize(table_name.underscore)
842
852
  # Are there multiple foreign keys out to the same table?
843
853
  assoc_name, need_class_name = _brick_get_hm_assoc_name(relation, assoc)
844
854
  if assoc.key?(:polymorphic)
@@ -846,8 +856,8 @@ class Object
846
856
  else
847
857
  need_fk = "#{ActiveSupport::Inflector.singularize(assoc[:inverse][:inverse_table].split('.').last)}_id" != assoc[:fk]
848
858
  end
849
- # fks[table_name].find { |other_assoc| other_assoc.object_id != assoc.object_id && other_assoc[:assoc_name] == assoc[assoc_name] }
850
- if (has_ones = ::Brick.config.has_ones&.fetch(model_name, nil))&.key?(singular_assoc_name = ActiveSupport::Inflector.singularize(assoc_name))
859
+ has_ones = ::Brick.config.has_ones&.fetch(full_name, nil)
860
+ if has_ones&.key?(singular_assoc_name = ActiveSupport::Inflector.singularize(assoc_name.tr('.', '_')))
851
861
  assoc_name = if (custom_assoc_name = has_ones[singular_assoc_name])
852
862
  need_class_name = custom_assoc_name != singular_assoc_name
853
863
  custom_assoc_name
@@ -1074,9 +1084,9 @@ class Object
1074
1084
  [built_controller, code]
1075
1085
  end
1076
1086
 
1077
- def _brick_get_hm_assoc_name(relation, hm_assoc)
1087
+ def _brick_get_hm_assoc_name(relation, hm_assoc, source = nil)
1078
1088
  if (relation[:hm_counts][hm_assoc[:assoc_name]]&.> 1) &&
1079
- hm_assoc[:alternate_name] != hm_assoc[:inverse][:assoc_name]
1089
+ hm_assoc[:alternate_name] != (source || name.underscore)
1080
1090
  plural = ActiveSupport::Inflector.pluralize(hm_assoc[:alternate_name])
1081
1091
  new_alt_name = (hm_assoc[:alternate_name] == name.underscore) ? "#{hm_assoc[:assoc_name].singularize}_#{plural}" : plural
1082
1092
  # uniq = 1
@@ -129,7 +129,11 @@ module Brick
129
129
  "#{assoc_name}\n"
130
130
  end
131
131
  else # has_one
132
- "<%= obj = #{obj_name}.#{hm.first}; link_to(obj.brick_descrip, obj) if obj %>\n"
132
+ # 0..62 because Postgres column names are limited to 63 characters
133
+ "<%= descrips = @_brick_bt_descrip[#{hm.first.inspect}][ho_class = #{hm[1].klass.name}]
134
+ ho_txt = ho_class.brick_descrip(#{obj_name}, descrips[0..-2].map { |id| #{obj_name}.send(id.last[0..62]) }, (ho_id_col = descrips.last))
135
+ ho_id = ho_id_col.map { |id_col| #{obj_name}.send(id_col.to_sym) }
136
+ ho_id&.first ? link_to(ho_txt, send(\"#\{ho_class.base_class.name.underscore.tr('/', '_')\}_path\".to_sym, ho_id)) : ho_txt %>\n"
133
137
  end
134
138
  when 'show', 'update'
135
139
  hm_stuff << if hm_fk_name
@@ -164,10 +168,10 @@ module Brick
164
168
  }
165
169
 
166
170
  #headerTop {
167
- position: sticky;
168
- top: 0px;
169
- background-color: white;
170
- z-index: 1;
171
+ position: sticky;
172
+ top: 0px;
173
+ background-color: white;
174
+ z-index: 1;
171
175
  }
172
176
  table {
173
177
  border-collapse: collapse;
@@ -214,9 +218,6 @@ table tbody tr.active-row {
214
218
  color: #009879;
215
219
  }
216
220
 
217
- td.val {
218
- display: block;
219
- }
220
221
  a.show-arrow {
221
222
  font-size: 1.5em;
222
223
  text-decoration: none;
@@ -236,6 +237,10 @@ a.big-arrow {
236
237
  .dimmed {
237
238
  background-color: #C0C0C0;
238
239
  }
240
+ .orphan {
241
+ color: red;
242
+ white-space: nowrap;
243
+ }
239
244
 
240
245
  #revertTemplate {
241
246
  display: none;
@@ -251,13 +256,13 @@ input+svg.revert {
251
256
  top: 0.5em;
252
257
  }
253
258
 
254
- input[type=submit] {
259
+ .update {
260
+ position: sticky;
261
+ right: 1em;
262
+ float: right;
255
263
  background-color: #004998;
256
264
  color: #FFF;
257
265
  }
258
- .right {
259
- text-align: right;
260
- }
261
266
  </style>
262
267
  <% is_includes_dates = nil
263
268
 
@@ -574,11 +579,11 @@ if (headerTop) {
574
579
  else
575
580
  bt_txt = (bt_class = bt[1].first.first).brick_descrip(
576
581
  # 0..62 because Postgres column names are limited to 63 characters
577
- #{obj_name}, (descrips = @_brick_bt_descrip[bt.first][bt_class])[0..-2].map { |z| #{obj_name}.send(z.last[0..62]) }, (bt_id_col = descrips.last)
582
+ #{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)
578
583
  )
579
- bt_txt ||= \"<< Orphaned ID: #\{val} >>\" if val
580
- bt_id = #{obj_name}.send(*bt_id_col) if bt_id_col&.present? %>
581
- <%= bt_id ? link_to(bt_txt, send(\"#\{bt_class.base_class.name.underscore.tr('/', '_')\}_path\".to_sym, bt_id)) : bt_txt %>
584
+ bt_txt ||= \"<span class=\\\"orphan\\\">&lt;&lt; Orphaned ID: #\{val} >></span>\".html_safe if val
585
+ bt_id = bt_id_col.map { |id_col| #{obj_name}.send(id_col.to_sym) } %>
586
+ <%= bt_id&.first ? link_to(bt_txt, send(\"#\{bt_class.base_class.name.underscore.tr('/', '_')\}_path\".to_sym, bt_id)) : bt_txt %>
582
587
  <%#= 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 %>
583
588
  <% end %>
584
589
  <% else %>
@@ -676,7 +681,7 @@ end
676
681
  <%= k %>
677
682
  <% end %>
678
683
  </th>
679
- <td class=\"val\">
684
+ <td>
680
685
  <% dt_pickers = { datetime: 'datetimepicker', timestamp: 'datetimepicker', time: 'timepicker', date: 'datepicker' }
681
686
  if bt
682
687
  html_options = { prompt: \"Select #\{bt_name\}\" }
@@ -685,22 +690,21 @@ end
685
690
  <%= if (bt_obj = bt_class&.find_by(bt_pair[1] => val))
686
691
  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' })
687
692
  elsif val
688
- \"<span>Orphaned ID: #\{val}</span>\".html_safe
693
+ \"<span class=\\\"orphan\\\">Orphaned ID: #\{val}</span>\".html_safe
689
694
  end %><svg class=\"revert\" width=\"1.5em\" viewBox=\"0 0 512 512\"><use xlink:href=\"#revertPath\" /></svg>
690
- <% else case (col_type = #{model_name}.column_for_attribute(k).type)
695
+ <% else
696
+ html_options = {}
697
+ html_options[:class] = 'dimmed' unless val
698
+ case (col_type = #{model_name}.column_for_attribute(k).type)
691
699
  when :string, :text %>
692
700
  <% if is_bcrypt?(val) # || .readonly? %>
693
701
  <%= hide_bcrypt(val, 1000) %>
694
702
  <% else %>
695
- <div class=\"wide-input\"><%= f.text_field k.to_sym %><svg class=\"revert\" width=\"1.5em\" viewBox=\"0 0 512 512\"><use xlink:href=\"#revertPath\" /></svg></div>
703
+ <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>
696
704
  <% end %>
697
705
  <% when :boolean %>
698
706
  <%= f.check_box k.to_sym %><svg class=\"revert\" width=\"1.5em\" viewBox=\"0 0 512 512\"><use xlink:href=\"#revertPath\" /></svg>
699
- <% when :integer, :decimal, :float
700
- # What happens when keys are UUID?
701
- # Postgres naturally uses the +uuid_generate_v4()+ function from the uuid-ossp extension
702
- # If it's not yet enabled then: enable_extension 'uuid-ossp'
703
- # ActiveUUID gem created a new :uuid type %>
707
+ <% when :integer, :decimal, :float %>
704
708
  <%= if col_type == :integer
705
709
  f.text_field k.to_sym, { pattern: '\\d*', class: 'check-validity' }
706
710
  else
@@ -709,6 +713,12 @@ end
709
713
  <% when *dt_pickers.keys
710
714
  is_includes_dates = true %>
711
715
  <%= 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>
716
+ <% when :uuid %>
717
+ <%=
718
+ # Postgres naturally uses the +uuid_generate_v4()+ function from the uuid-ossp extension
719
+ # If it's not yet enabled then: enable_extension 'uuid-ossp'
720
+ # ActiveUUID gem created a new :uuid type
721
+ val %>
712
722
  <% when :binary, :primary_key %>
713
723
  <% end %>
714
724
  <% end %>
@@ -716,7 +726,7 @@ end
716
726
  </tr>
717
727
  <% end
718
728
  if has_fields %>
719
- <tr><td colspan=\"2\" class=\"right\"><%= f.submit %></td></tr>
729
+ <tr><td colspan=\"2\"><%= f.submit({ class: 'update' }) %></td></tr>
720
730
  <% else %>
721
731
  <tr><td colspan=\"2\">(No displayable fields)</td></tr>
722
732
  <% end %>
@@ -5,7 +5,7 @@ module Brick
5
5
  module VERSION
6
6
  MAJOR = 1
7
7
  MINOR = 0
8
- TINY = 43
8
+ TINY = 46
9
9
 
10
10
  # PRE is nil unless it's a pre-release (beta, RC, etc.)
11
11
  PRE = nil
@@ -224,7 +224,7 @@ module Brick
224
224
  # # Database schema to use when analysing existing data, such as deriving a list of polymorphic classes in the case that
225
225
  # # it wasn't originally specified.
226
226
  # Brick.schema_behavior = :namespaced
227
- #{Brick.config.schema_behavior ? "Brick.schema_behavior = { multitenant: { schema_to_analyse: #{
227
+ #{Brick.config.schema_behavior.present? ? "Brick.schema_behavior = { multitenant: { schema_to_analyse: #{
228
228
  Brick.config.schema_behavior[:multitenant]&.fetch(:schema_to_analyse, nil).inspect}" :
229
229
  "# Brick.schema_behavior = { multitenant: { schema_to_analyse: 'engineering'"
230
230
  } } }
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.43
4
+ version: 1.0.46
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 00:00:00.000000000 Z
11
+ date: 2022-07-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord