brick 1.0.64 → 1.0.65

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: c48ee6a2f143563e2e443f6edf0dc0e04e800e8fae6951e05b0362956129e950
4
- data.tar.gz: f632f6e795dcf9b3aeb97e36a37c8074302c5967206b5f415a9a4b862bb4fda7
3
+ metadata.gz: 8a69a2b2fabbd8850a4484ae743c51ea895329d984638b0d7448a020859163f3
4
+ data.tar.gz: 46e5b56d1606aeaa1489b12462c417eabba871eca5cd018c223f915092157e11
5
5
  SHA512:
6
- metadata.gz: 0cd5e05899a2f780a0bbf378f8f49e49f604b90cf122f2cd7efe34839c434af814c9a228f36bd18b112cd8e40b6736e88742ea0f2a1a0b55ac3f8f573e614918
7
- data.tar.gz: a34a9f47746159f6b4b39f8a3cd994055e022be9eefe8737b73c63e5d475b283ae3b99a6a11e3faf140ca6efbf67d7f400e03147a757c237c8875f11ea2c0ea4
6
+ metadata.gz: e4817d2bef72c2e8082eee5762616f72b1e1c360ac395bb79b2272ceffa46849f7da89b72f99044875f70d688970f2529d9d9bb1ddea3b1b3adbe816d608345f
7
+ data.tar.gz: c992c1d4979ee36e8eaa4a6d575c5e19defafd926b2c30aa73ea0c2c4c1789f8418431b8e1af7b0832d747c26e2861b91eed070725004746d25255a74d984571
@@ -257,7 +257,7 @@ module ActiveRecord
257
257
  # For our purposes a :has_one is similar enough to a :belongs_to that we can just join forces
258
258
  _br_bt_descrip[k] = { hm.klass => hm.klass.brick_parse_dsl(join_array, k, translations) }
259
259
  else # Standard :has_many
260
- _br_hm_counts[k] = hm
260
+ _br_hm_counts[k] = hm unless hm.options[:through] && !_br_associatives.fetch(hm.name, nil)
261
261
  end
262
262
  end
263
263
  end
@@ -398,7 +398,7 @@ module ActiveRecord
398
398
  if selects&.empty? # Default to all columns
399
399
  tbl_no_schema = table.name.split('.').last
400
400
  columns.each do |col|
401
- col_alias = ' AS _class' if (col_name = col.name) == 'class'
401
+ col_alias = " AS _#{col.name}" if (col_name = col.name) == 'class'
402
402
  selects << if is_mysql
403
403
  "`#{tbl_no_schema}`.`#{col_name}`#{col_alias}"
404
404
  else
@@ -479,24 +479,25 @@ module ActiveRecord
479
479
  end
480
480
  next unless count_column # %%% Would be able to remove this when multiple foreign keys to same destination becomes bulletproof
481
481
 
482
- tbl_alias = "_br_#{hm.name}"
482
+ tbl_alias = is_mysql ? "`_br_#{hm.name}`" : "\"_br_#{hm.name}\""
483
483
  pri_tbl = hm.active_record
484
+ pri_tbl_name = is_mysql ? "`#{pri_tbl.table_name}`" : "\"#{pri_tbl.table_name.gsub('.', '"."')}\""
484
485
  on_clause = []
485
486
  if fk_col.is_a?(Array) # Composite key?
486
- fk_col.each_with_index { |fk_col_part, idx| on_clause << "#{tbl_alias}.#{fk_col_part} = #{pri_tbl.table_name}.#{pri_tbl.primary_key[idx]}" }
487
+ fk_col.each_with_index { |fk_col_part, idx| on_clause << "#{tbl_alias}.#{fk_col_part} = #{pri_tbl_name}.#{pri_tbl.primary_key[idx]}" }
487
488
  selects = fk_col.dup
488
489
  else
489
490
  selects = [fk_col]
490
- on_clause << "#{tbl_alias}.#{fk_col} = #{pri_tbl.table_name}.#{pri_tbl.primary_key}"
491
+ on_clause << "#{tbl_alias}.#{fk_col} = #{pri_tbl_name}.#{pri_tbl.primary_key}"
491
492
  end
492
493
  if poly_type
493
494
  selects << poly_type
494
495
  on_clause << "#{tbl_alias}.#{poly_type} = '#{name}'"
495
496
  end
497
+ hm_table_name = is_mysql ? "`#{associative&.table_name || hm.klass.table_name}`" : "\"#{(associative&.table_name || hm.klass.table_name).gsub('.', '"."')}\""
496
498
  join_clause = "LEFT OUTER
497
499
  JOIN (SELECT #{selects.join(', ')}, COUNT(#{'DISTINCT ' if hm.options[:through]}#{count_column
498
- }) AS _ct_ FROM #{associative&.table_name || hm.klass.table_name
499
- } GROUP BY #{(1..selects.length).to_a.join(', ')}) AS #{tbl_alias}"
500
+ }) AS _ct_ FROM #{hm_table_name} GROUP BY #{(1..selects.length).to_a.join(', ')}) AS #{tbl_alias}"
500
501
  joins!("#{join_clause} ON #{on_clause.join(' AND ')}")
501
502
  end
502
503
  where!(wheres) unless wheres.empty?
@@ -1016,6 +1017,7 @@ class Object
1016
1017
  table_name = ActiveSupport::Inflector.underscore(plural_class_name)
1017
1018
  singular_table_name = ActiveSupport::Inflector.singularize(table_name)
1018
1019
  pk = model&._brick_primary_key(relations.fetch(table_name, nil))
1020
+ is_mysql = ActiveRecord::Base.connection.adapter_name == 'Mysql2'
1019
1021
 
1020
1022
  namespace_name = "#{namespace.name}::" if namespace
1021
1023
  code = +"class #{namespace_name}#{class_name} < ApplicationController\n"
@@ -1119,7 +1121,9 @@ class Object
1119
1121
  @_brick_params = (ar_relation = model.all).brick_select(params, (selects = []), order_by, translations, join_array)
1120
1122
  # %%% Add custom HM count columns
1121
1123
  # %%% What happens when the PK is composite?
1122
- counts = model._br_hm_counts.each_with_object([]) { |v, s| s << "_br_#{v.first}._ct_ AS _br_#{v.first}_ct" }
1124
+ counts = model._br_hm_counts.each_with_object([]) do |v, s|
1125
+ s << (is_mysql ? "`_br_#{v.first}`._ct_ AS \"_br_#{v.first}_ct\"" : "\"_br_#{v.first}\"._ct_ AS \"_br_#{v.first}_ct\"")
1126
+ end
1123
1127
  instance_variable_set("@#{table_name}".to_sym, ar_relation.dup._select!(*selects, *counts))
1124
1128
  if namespace && (idx = lookup_context.prefixes.index(table_name))
1125
1129
  lookup_context.prefixes[idx] = "#{namespace.name.underscore}/#{lookup_context.prefixes[idx]}"
@@ -1525,7 +1529,9 @@ module ActiveRecord::ConnectionHandling
1525
1529
 
1526
1530
  def retrieve_schema_and_tables(sql = nil, is_postgres = nil, schema = nil)
1527
1531
  sql ||= "SELECT t.table_schema AS \"schema\", t.table_name AS relation_name, t.table_type,#{"
1528
- pg_catalog.obj_description((t.table_schema || '.' || t.table_name)::regclass, 'pg_class') AS table_description," if is_postgres}
1532
+ pg_catalog.obj_description(
1533
+ ('\"' || t.table_schema || '\".\"' || t.table_name || '\"')::regclass, 'pg_class'
1534
+ ) AS table_description," if is_postgres}
1529
1535
  c.column_name, c.data_type,
1530
1536
  COALESCE(c.character_maximum_length, c.numeric_precision) AS max_length,
1531
1537
  tc.constraint_type AS const, kcu.constraint_name AS \"key\",
@@ -1595,6 +1601,8 @@ module Brick
1595
1601
  "#{bt_assoc_name}_bt"
1596
1602
  end
1597
1603
  end
1604
+ bt_assoc_name = "_#{bt_assoc_name}" if bt_assoc_name == 'attribute'
1605
+
1598
1606
  # %%% Temporary schema patch
1599
1607
  for_tbl = fk[1]
1600
1608
  apartment = Object.const_defined?('Apartment') && Apartment
@@ -118,7 +118,9 @@ module Brick
118
118
  hm_stuff = [(hm_assoc = hm.last),
119
119
  "H#{hm_assoc.macro == :has_one ? 'O' : 'M'}#{'T' if hm_assoc.options[:through]}",
120
120
  (assoc_name = hm.first)]
121
- hm_fk_name = if hm_assoc.options[:through]
121
+ hm_fk_name = if (through = hm_assoc.options[:through])
122
+ next unless @_brick_model.instance_methods.include?(through)
123
+
122
124
  associative = @_brick_model._br_associatives[hm.first]
123
125
  tbl_nm = if hm_assoc.options[:source]
124
126
  associative.klass.reflect_on_association(hm_assoc.options[:source]).inverse_of&.name
@@ -183,7 +185,7 @@ h1, h3 {
183
185
  margin-bottom: 0;
184
186
  }
185
187
  #imgErd {
186
- background-image:url(assets/brick_erd.png);
188
+ background-image:url(/assets/brick_erd.png);
187
189
  background-size: 100% 100%;
188
190
  width: 2.2em;
189
191
  height: 2.2em;
@@ -534,6 +536,65 @@ if (headerTop) {
534
536
  }, true);
535
537
  }
536
538
  </script>"
539
+
540
+ erd_markup = "<div id=\"mermaidErd\" class=\"mermaid\">
541
+ erDiagram
542
+ <% model_short_name = #{@_brick_model.name.split('::').last.inspect}
543
+ callbacks = {}
544
+ @_brick_bt_descrip&.each do |bt|
545
+ bt_class = bt[1].first.first
546
+ callbacks[bt_name = bt_class.name.split('::').last] = bt_class
547
+ is_has_one = #{@_brick_model.name}.reflect_on_association(bt.first).inverse_of&.macro == :has_one ||
548
+ ::Brick.config.has_ones&.fetch('#{@_brick_model.name}', nil)&.key?(bt.first.to_s)
549
+ %> <%= \"#\{model_short_name} #\{is_has_one ? '||' : '}o'}--|| #\{bt_name} : \\\"#\{
550
+ bt.first unless bt.first.to_s == bt[1].first.first.name.underscore.singularize.tr('/', '_')
551
+ }\\\"\".html_safe %>
552
+ <% end
553
+ last_through = nil
554
+ @_brick_hm_counts&.each do |hm|
555
+ # Skip showing self-referencing HM links since they would have already been drawn while evaluating the BT side
556
+ next if (hm_class = hm.last&.klass) == #{@_brick_model.name}
557
+
558
+ callbacks[hm_name = hm_class.name.split('::').last] = hm_class
559
+ if (through = hm.last.options[:through]&.to_s) # has_many :through (HMT)
560
+ callbacks[through.singularize.camelize] = (through_assoc = hm.last.source_reflection).active_record
561
+ if last_through == through # Same HM, so no need to build it again, and for clarity just put in a blank line
562
+ %><%= \"\n\"
563
+ %><% else
564
+ %> <%= \"#\{model_short_name} ||--o{ #\{through_assoc.active_record.name}\".html_safe %> : \"\"
565
+ <% last_through = through
566
+ end
567
+ %> <%= \"#\{through_assoc.active_record.name} }o--|| #\{hm_name}\".html_safe %> : \"\"
568
+ <%= \"#\{model_short_name} }o..o{ #\{hm_name} : \\\"#\{hm.first}\\\"\".html_safe %><%
569
+ else # has_many
570
+ %> <%= \"#\{model_short_name} ||--o{ #\{hm_name} : \\\"#\{
571
+ hm_name unless hm.first.to_s == hm_class.name.underscore.pluralize.tr('/', '_')
572
+ }\\\"\".html_safe %><%
573
+ end %>
574
+ <% end
575
+ callbacks.merge({model_short_name => #{@_brick_model.name}}).each do |cb_k, cb_class|
576
+ cb_relation = ::Brick.relations[cb_class.table_name]
577
+ pkeys = cb_relation[:pkey]&.first&.last
578
+ fkeys = cb_relation[:fks]&.values&.each_with_object([]) { |fk, s| s << fk[:fk] if fk.fetch(:is_bt, nil) }
579
+ %> <%= cb_k %> {<%
580
+ pkeys&.each do |pk| %>
581
+ <%= \"int #\{pk} \\\"PK#\{' fk' if fkeys&.include?(pk)}\\\"\".html_safe %><%
582
+ end %><%
583
+ fkeys&.each do |fk|
584
+ if fk.is_a?(Array)
585
+ fk.each do |fk_part| %>
586
+ <%= \"int #\{fk_part} \\\"&nbsp;&nbsp;&nbsp;&nbsp;fk\\\"\".html_safe unless pkeys&.include?(fk_part) %><%
587
+ end
588
+ else %>
589
+ <%= \"int #\{fk} \\\"&nbsp;&nbsp;&nbsp;&nbsp;fk\\\"\".html_safe unless pkeys&.include?(fk) %><%
590
+ end
591
+ end %>
592
+ }
593
+ <% end
594
+ # callback < %= cb_k % > erdClick
595
+ %>
596
+ </div>
597
+ "
537
598
  inline = case args.first
538
599
  when 'index'
539
600
  obj_pk = if pk&.is_a?(Array) # Composite primary key?
@@ -670,68 +731,9 @@ if (headerTop) {
670
731
  });
671
732
  });
672
733
  </script>
673
- <% end
674
- if true # @_brick_erd
675
- %><div id=\"mermaidErd\" class=\"mermaid\">
676
- erDiagram
677
- <% model_short_name = #{@_brick_model.name.split('::').last.inspect}
678
- callbacks = {}
679
- @_brick_bt_descrip.each do |bt|
680
- bt_class = bt[1].first.first
681
- callbacks[bt_name = bt_class.name.split('::').last] = bt_class
682
- is_has_one = #{@_brick_model.name}.reflect_on_association(bt.first).inverse_of&.macro == :has_one ||
683
- ::Brick.config.has_ones&.fetch('#{@_brick_model.name}', nil)&.key?(bt.first.to_s)
684
- %> <%= \"#\{model_short_name} #\{is_has_one ? '||' : '}o'}--|| #\{bt_name} : \\\"#\{
685
- bt.first unless bt.first.to_s == bt[1].first.first.name.underscore.singularize.tr('/', '_')
686
- }\\\"\".html_safe %>
687
- <% end
688
- last_through = nil
689
- @_brick_hm_counts.each do |hm|
690
- # Skip showing self-referencing HM links since they would have already been drawn while evaluating the BT side
691
- next if (hm_class = hm.last.klass) == #{@_brick_model.name}
692
-
693
- callbacks[hm_name = hm_class.name.split('::').last] = hm_class
694
- if (through = hm.last.options[:through]&.to_s) # has_many :through (HMT)
695
- callbacks[through.singularize.camelize] = (through_assoc = hm.last.source_reflection).active_record
696
- if last_through == through # Same HM, so no need to build it again, and for clarity just put in a blank line
697
- %><%= \"\n\"
698
- %><% else
699
- %> <%= \"#\{model_short_name} ||--o{ #\{through_assoc.active_record.name}\".html_safe %> : \"\"
700
- <% last_through = through
701
- end
702
- %> <%= \"#\{through_assoc.active_record.name} }o--|| #\{hm_name}\".html_safe %> : \"\"
703
- <%= \"#\{model_short_name} }o..o{ #\{hm_name} : \\\"#\{hm.first}\\\"\".html_safe %><%
704
- else # has_many
705
- %> <%= \"#\{model_short_name} ||--o{ #\{hm_name} : \\\"#\{
706
- hm_name unless hm.first.to_s == hm_class.name.underscore.pluralize.tr('/', '_')
707
- }\\\"\".html_safe %><%
708
- end %>
709
- <% end
710
- callbacks.merge({model_short_name => #{@_brick_model.name}}).each do |cb_k, cb_class|
711
- cb_relation = ::Brick.relations[cb_class.table_name]
712
- pkeys = cb_relation[:pkey]&.first&.last
713
- fkeys = cb_relation[:fks]&.values&.each_with_object([]) { |fk, s| s << fk[:fk] if fk.fetch(:is_bt, nil) }
714
- %> <%= cb_k %> {<%
715
- pkeys&.each do |pk| %>
716
- <%= \"int #\{pk} \\\"PK#\{' fk' if fkeys&.include?(pk)}\\\"\".html_safe %><%
717
- end %><%
718
- fkeys&.each do |fk|
719
- if fk.is_a?(Array)
720
- fk.each do |fk_part| %>
721
- <%= \"int #\{fk_part} \\\"&nbsp;&nbsp;&nbsp;&nbsp;fk\\\"\".html_safe unless pkeys&.include?(fk_part) %><%
722
- end
723
- else %>
724
- <%= \"int #\{fk} \\\"&nbsp;&nbsp;&nbsp;&nbsp;fk\\\"\".html_safe unless pkeys&.include?(fk) %><%
725
- end
726
- end %>
727
- }
728
- <% end
729
- # callback < %= cb_k % > erdClick
730
- %>
731
- </div>
732
- <% end
733
-
734
- %><table id=\"headerTop\"></table>
734
+ <% end %>
735
+ #{erd_markup}
736
+ <table id=\"headerTop\"></table>
735
737
  <table id=\"#{table_name}\" class=\"shadow\">
736
738
  <thead><tr>#{"<th x-order=\"#{pk.join(',')}\"></th>" if pk.present?}<%=
737
739
  # Consider getting the name from the association -- hm.first.name -- if a more \"friendly\" alias should be used for a screwy table name
@@ -905,6 +907,7 @@ if (description = (relation = Brick.relations[#{model_name}.table_name])&.fetch(
905
907
  description %><br><%
906
908
  end
907
909
  %><%= link_to '(See all #{obj_name.pluralize})', #{path_obj_name.pluralize}_path %>
910
+ #{erd_markup}
908
911
  <% if obj %>
909
912
  <br><br>
910
913
  <%= # path_options = [obj.#{pk}]
@@ -5,7 +5,7 @@ module Brick
5
5
  module VERSION
6
6
  MAJOR = 1
7
7
  MINOR = 0
8
- TINY = 64
8
+ TINY = 65
9
9
 
10
10
  # PRE is nil unless it's a pre-release (beta, RC, etc.)
11
11
  PRE = 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.64
4
+ version: 1.0.65
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-08-28 00:00:00.000000000 Z
11
+ date: 2022-08-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord