brick 1.0.132 → 1.0.134

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: '08cc0b19ab0838b667534f4de64f3a7045bf395202a3602981a20ececdc91ab5'
4
- data.tar.gz: 4b976489a05bb26c3702746700025c6bad3bb930fc129ae897bc9e1596a50901
3
+ metadata.gz: 613c6296c56af562bc77d55d734b0a6e5bdad7e3942891db4dc939fe087fca7f
4
+ data.tar.gz: acc5873eeae8a0d9e9d4a86cc8b71ee12dc0699821dee132c40c569147156075
5
5
  SHA512:
6
- metadata.gz: 580db611d4ab9e2bf7ab0ed62a90940b90a4818619a9a91788802f017845c0aef3c8da1b01ea8a6a87c8e1af8378dc5c0d030396ebebba05d101b46ca0bd4495
7
- data.tar.gz: fe876de91852b7213fa4d35b378935c7f18e18ae09ff5058f0d34b32dcb3c802a15d1c2cc79f63f7b5eac4177b7bbbeae43603e55499447cfee9e1d3556f64fa
6
+ metadata.gz: 046bec9f177ec74aaa3bbba3ef1dd2afe54f43376068ed657ed0fec6d18ac353e8addfabad514fdf33cc6199d053ca1e23c0f46aa1a53cac96fe6e21f7a50796
7
+ data.tar.gz: 7d21817ea8774f65852be247ae72c341559c84b0a58228d019d5630036827a99988699752392bbc43330400761ea9e59292231bae5993fa0620240126fe7490e
data/lib/brick/config.rb CHANGED
@@ -258,7 +258,9 @@ module Brick
258
258
  else
259
259
  # Custom STI type columns for models built from specific tables
260
260
  (v.last.is_a?(Array) ? v.last : [v.last]).each do |table|
261
- ::Brick.relations[table][:sti_col] = v.first
261
+ if (relation = ::Brick.relations.fetch(table, nil))
262
+ relation[:sti_col] = v.first
263
+ end
262
264
  end
263
265
  end
264
266
  end
@@ -44,9 +44,20 @@
44
44
 
45
45
  module ActiveRecord
46
46
  class Base
47
+ @_brick_inheriteds = {}
47
48
  class << self
48
49
  attr_reader :_brick_relation
49
50
 
51
+ def _brick_inheriteds
52
+ @_brick_inheriteds ||= ::ActiveRecord::Base.instance_variable_get(:@_brick_inheriteds)
53
+ end
54
+
55
+ # Track the file(s) in which each model is defined
56
+ def inherited(model)
57
+ (_brick_inheriteds[model] ||= []) << caller.first.split(':')[0..1] unless caller.first.include?('/lib/brick/extensions.rb:')
58
+ super
59
+ end
60
+
50
61
  def is_brick?
51
62
  instance_variables.include?(:@_brick_built) && instance_variable_get(:@_brick_built)
52
63
  end
@@ -659,7 +670,6 @@ module ActiveRecord
659
670
  # Add derived table JOIN for the has_many counts
660
671
  nix = []
661
672
  klass._br_hm_counts.each do |k, hm|
662
- num_bt_things = 0
663
673
  count_column = if hm.options[:through]
664
674
  # Build the chain of JOINs going to the final destination HMT table
665
675
  # (Usually just one JOIN, but could be many.)
@@ -680,7 +690,11 @@ module ActiveRecord
680
690
  # Turn the last member of link_back into a foreign key
681
691
  link_back << hmt_assoc.source_reflection.foreign_key
682
692
  # If it's a HMT based on a HM -> HM, must JOIN the last table into the mix at the end
683
- through_sources.push(hm.source_reflection) unless hm.source_reflection.belongs_to?
693
+ this_hm = hm
694
+ while !(src_ref = this_hm.source_reflection).belongs_to? && (thr = src_ref.options[:through])
695
+ through_sources.push(this_hm = src_ref.active_record.reflect_on_association(thr))
696
+ end
697
+ through_sources.push(src_ref) unless src_ref.belongs_to?
684
698
  from_clause = +"#{through_sources.first.table_name} br_t0"
685
699
  fk_col = through_sources.shift.foreign_key
686
700
 
@@ -689,9 +703,7 @@ module ActiveRecord
689
703
  through_sources.map do |a|
690
704
  from_clause << "\n LEFT OUTER JOIN #{a.table_name} br_t#{idx += 1} "
691
705
  from_clause << if (src_ref = a.source_reflection).macro == :belongs_to
692
- nm = hmt_assoc.source_reflection.inverse_of&.name
693
- link_back << nm
694
- num_bt_things += 1
706
+ link_back << (nm = hmt_assoc.source_reflection.inverse_of&.name)
695
707
  # puts "BT #{a.table_name}"
696
708
  "ON br_t#{idx}.#{a.active_record.primary_key} = br_t#{idx - 1}.#{a.foreign_key}"
697
709
  elsif src_ref.options[:as]
@@ -712,9 +724,8 @@ module ActiveRecord
712
724
  end
713
725
  else # Standard has_many or has_one
714
726
  # puts "HM #{a.table_name}"
715
- # binding.pry unless (
716
727
  nm = hmt_assoc.source_reflection.inverse_of&.name
717
- # )
728
+ # binding.pry unless nm
718
729
  link_back << nm # if nm
719
730
  "ON br_t#{idx}.#{a.foreign_key} = br_t#{idx - 1}.#{a.active_record.primary_key}"
720
731
  end
@@ -731,16 +742,8 @@ module ActiveRecord
731
742
  nix << k
732
743
  next
733
744
  elsif src_ref.macro == :belongs_to # Traditional HMT using an associative table
734
- # binding.pry if link_back.length > 2
735
745
  "br_t#{idx}.#{hm.foreign_key}"
736
746
  else # A HMT that goes HM -> HM, something like Categories -> Products -> LineItems
737
- # %%% Currently flaky, so will revisit this soon, probably while implementing the whole link_back architecture
738
- if num_bt_things > 1
739
- # binding.pry
740
- nix << k
741
- next
742
- end
743
-
744
747
  "br_t#{idx}.#{src_ref.active_record.primary_key}"
745
748
  end
746
749
  else
@@ -2743,31 +2746,15 @@ module Brick
2743
2746
  end
2744
2747
  end
2745
2748
  abstract_activerecord_bases = ::Brick.eager_load_classes(true)
2746
- models = if Dir.exist?(model_path = "#{rails_root}/app/models")
2747
- Dir["#{model_path}/**/*.rb"].each_with_object({}) do |path, s|
2748
- modules = []
2749
- File.read(path).split("\n").each do |line|
2750
- # Capture a list of modules leading up to this class
2751
- if line.lstrip.start_with?('module ') && (idx = line.index('module'))
2752
- modules << line[idx + 6..-1].match(/[\s:]+([\w:]+)/)&.captures&.first
2753
- end
2754
- # For all non-commented lines, look for any that start with "class " and also "< ApplicationRecord"
2755
- if line.lstrip.start_with?('class ') && (idx = line.index('class')) &&
2756
- (model_name = line[idx + 5..-1].match(/[\s:]+([\w:]+)/)&.captures&.first)
2757
- # Prefix model class name with module names, if any
2758
- model_name = modules.map{|m| "#{m}::"}.join + model_name
2759
- unless abstract_activerecord_bases.include?(model_name)
2760
- klass = begin
2761
- model_name.constantize
2762
- rescue
2763
- end
2764
- s[model_name.underscore.tr('/', '.').pluralize] = [
2765
- path.start_with?(rails_root) ? path[rails_root.length + 1..-1] : path,
2766
- klass
2767
- ]
2768
- end
2769
- end
2749
+ rails_root = ::Rails.root.to_s
2750
+ models = ::Brick.relations.each_with_object({}) do |rel, s|
2751
+ begin
2752
+ if (model = rel.last[:class_name]&.constantize) &&
2753
+ (inh = ActiveRecord::Base._brick_inheriteds[model]&.join(':'))
2754
+ inh = inh[rails_root.length + 1..-1] if inh.start_with?(rails_root)
2755
+ s[rel.first] = [inh, model]
2770
2756
  end
2757
+ rescue
2771
2758
  end
2772
2759
  end
2773
2760
  ::Brick.relations.map do |k, v|
@@ -2781,7 +2768,8 @@ module Brick
2781
2768
  v[:class_name].constantize.table_name
2782
2769
  rescue
2783
2770
  end
2784
- [k, table_name || k, migrations&.fetch(res, nil), model&.first]
2771
+ model = model.first if model.is_a?(Array)
2772
+ [k, table_name || k, migrations&.fetch(res, nil), model]
2785
2773
  end
2786
2774
  end
2787
2775
 
@@ -61,9 +61,11 @@ module Brick
61
61
  ::Brick::Rails.display_binary(val)
62
62
  else
63
63
  if col_type
64
- if lat_lng
64
+ if lat_lng && !(lat_lng.first.zero? && lat_lng.last.zero?)
65
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
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
+ elsif val.is_a?(Numeric)
68
+ ::ActiveSupport::NumberHelper.number_to_delimited(val, delimiter: ',')
67
69
  else
68
70
  ::Brick::Rails::FormBuilder.hide_bcrypt(val, col_type == :xml)
69
71
  end
@@ -922,6 +924,9 @@ a.big-arrow {
922
924
  background-color: #C0C0C0;
923
925
  text-align: center;
924
926
  }
927
+ .right {
928
+ text-align: right;
929
+ }
925
930
  .orphan {
926
931
  color: red;
927
932
  white-space: nowrap;
@@ -1110,6 +1115,14 @@ if (headerTop) {
1110
1115
  setHeaderSizes();
1111
1116
  }, true);
1112
1117
  }
1118
+ // Cause descriptive text to use the same font as the resource
1119
+ var brickFontFamily = document.getElementById(\"resourceName\").computedStyleMap().get(\"font-family\");
1120
+ if (window.brickFontFamily) {
1121
+ [...document.getElementsByClassName(\"__brick\")].forEach(function (x){
1122
+ if (!x.style.fontFamily)
1123
+ x.style.fontFamily = brickFontFamily.toString();
1124
+ });
1125
+ }
1113
1126
  </script>"
1114
1127
 
1115
1128
  erd_markup = if @_brick_model
@@ -1354,8 +1367,8 @@ end
1354
1367
  %><%= if (page_num = @#{table_name}._brick_page_num)
1355
1368
  \"<tr><td colspan=\\\"#\{td_count}\\\">Page #\{page_num}</td></tr>\".html_safe
1356
1369
  end %></table>#{template_link}<%
1357
- if description.present? %><%=
1358
- description %><br><%
1370
+ if description.present? %><span class=\"__brick\"><%=
1371
+ description %></span><br><%
1359
1372
  end
1360
1373
  # FILTER PARAMETERS
1361
1374
  if @_brick_params&.present? %>
@@ -1366,12 +1379,12 @@ end
1366
1379
  if (destination_fk = Brick.relations[origin.table_name][:fks].values.find { |fk| fk[:fk] == key_parts.last }) &&
1367
1380
  (objs = (destination = origin.reflect_on_association(destination_fk[:assoc_name])&.klass)&.find(id))
1368
1381
  objs = [objs] unless objs.is_a?(Array) %>
1369
- <h3>for <% objs.each do |obj| %><%=
1382
+ <h3 class=\"__brick\">for <% objs.each do |obj| %><%=
1370
1383
  link_to \"#{"#\{obj.brick_descrip\} (#\{destination.name\})\""}, send(\"#\{destination._brick_index(:singular)\}_path\".to_sym, id)
1371
1384
  %><% end %></h3><%
1372
1385
  end
1373
1386
  end %>
1374
- (<%= link_to \"See all #\{model.base_class.name.split('::').last.pluralize}\", #{@_brick_model._brick_index}_path %>)
1387
+ <span class=\"__brick\">(<%= link_to \"See all #\{model.base_class.name.split('::').last.pluralize}\", #{@_brick_model._brick_index}_path %>)</span>
1375
1388
  <% end
1376
1389
  # COLUMN EXCLUSIONS
1377
1390
  if @_brick_excl&.present? %>
@@ -1422,7 +1435,7 @@ end
1422
1435
  cols, poly_cols, bts, #{hms_keys.inspect}, {#{hms_columns.join(', ')}}) %>
1423
1436
 
1424
1437
  #{"<hr><%= link_to(\"New #{new_path_name = "new_#{path_obj_name}_path"
1425
- obj_name}\", #{new_path_name}) if respond_to?(:#{new_path_name}) %>" unless @_brick_model.is_view?}
1438
+ obj_name}\", #{new_path_name}, { class: '__brick' }) if respond_to?(:#{new_path_name}) %>" unless @_brick_model.is_view?}
1426
1439
  #{script}
1427
1440
  </body>
1428
1441
  </html>
@@ -1534,7 +1547,7 @@ end
1534
1547
  <p style=\"color: green\"><%= notice if request.respond_to?(:flash) %></p>#{"
1535
1548
  #{schema_options}" if schema_options}
1536
1549
  <select id=\"tbl\">#{table_options}</select>
1537
- <table><td><h1><%= page_title %></h1></td>
1550
+ <table id=\"resourceName\"><td><h1><%= page_title %></h1></td>
1538
1551
  <% if Object.const_defined?('Avo') && ::Avo.respond_to?(:railtie_namespace) %>
1539
1552
  <td><%= link_to_brick(
1540
1553
  avo_svg,
@@ -1560,10 +1573,10 @@ end
1560
1573
  end %>
1561
1574
  </table>
1562
1575
  <%
1563
- if (description = (relation = Brick.relations[#{model_name}.table_name])&.fetch(:description, nil)) %><%=
1564
- description %><br><%
1576
+ if (description = (relation = Brick.relations[#{model_name}.table_name])&.fetch(:description, nil)) %>
1577
+ <span class=\"__brick\"><%= description %></span><br><%
1565
1578
  end
1566
- %><%= link_to \"(See all #\{model_name.pluralize})\", see_all_path %>
1579
+ %><%= link_to \"(See all #\{model_name.pluralize})\", see_all_path, { class: '__brick' } %>
1567
1580
  #{erd_markup}
1568
1581
  <% if obj
1569
1582
  # path_options = [obj.#{pk}]
@@ -1647,7 +1660,8 @@ end
1647
1660
  #{unless args.first == 'new'
1648
1661
  # Was: confirm_are_you_sure = ActionView.version < ::Gem::Version.new('7.0') ? "data: { confirm: 'Delete #\{model_name} -- Are you sure?' }" : "form: { data: { turbo_confirm: 'Delete #\{model_name} -- Are you sure?' } }"
1649
1662
  confirm_are_you_sure = "data: { confirm: 'Delete #\{model_name} -- Are you sure?' }"
1650
- hms_headers.each_with_object(+'') do |hm, s|
1663
+ ret = +"<%= button_to(\"Delete #\{@#{obj_name}.brick_descrip}\", send(\"#\{#{model_name}._brick_index(:singular)}_path\".to_sym, @#{obj_name}), { method: 'delete', class: 'danger', #{confirm_are_you_sure} }) %>"
1664
+ hms_headers.each_with_object(ret) do |hm, s|
1651
1665
  # %%% Would be able to remove this when multiple foreign keys to same destination becomes bulletproof
1652
1666
  next if hm.first.options[:through] && !hm.first.through_reflection
1653
1667
 
@@ -1707,8 +1721,7 @@ end
1707
1721
  else
1708
1722
  s
1709
1723
  end
1710
- end +
1711
- "<%= button_to(\"Delete #\{@#{obj_name}.brick_descrip}\", send(\"#\{#{model_name}._brick_index(:singular)}_path\".to_sym, @#{obj_name}), { method: 'delete', class: 'danger', #{confirm_are_you_sure} }) %>"
1724
+ end
1712
1725
  end}
1713
1726
  <% end %>
1714
1727
  #{script}
@@ -1793,7 +1806,8 @@ flatpickr(\".timepicker\", {enableTime: true, noCalendar: true});
1793
1806
 
1794
1807
  mermaidCode = document.createElement(\"SCRIPT\");
1795
1808
  mermaidCode.setAttribute(\"src\", \"https://cdn.jsdelivr.net/npm/mermaid@9.1.7/dist/mermaid.min.js\");
1796
- mermaidCode.addEventListener(\"load\", function () {
1809
+ mermaidCode.addEventListener(\"load\", mermaidLoaded);
1810
+ function mermaidLoaded() {
1797
1811
  mermaid.initialize({
1798
1812
  startOnLoad: true,
1799
1813
  securityLevel: \"loose\",
@@ -1826,6 +1840,14 @@ flatpickr(\".timepicker\", {enableTime: true, noCalendar: true});
1826
1840
  window.history.pushState({}, '', changeout(location.href, '_brick_erd', null));
1827
1841
  });
1828
1842
  mermaidErd.appendChild(span);
1843
+ }
1844
+ // If there's an error with the CDN during load, revert to our local copy
1845
+ mermaidCode.addEventListener(\"error\", function (e) {
1846
+ console.warn(\"As we're unable to load Mermaid from\\n \" + e.srcElement.src + \" ,\\nnow reverting to copy from /assets.\");
1847
+ var mermaidCode2 = document.createElement(\"SCRIPT\");
1848
+ mermaidCode2.setAttribute(\"src\", \"/assets/mermaid.min.js\");
1849
+ mermaidCode2.addEventListener(\"load\", mermaidLoaded);
1850
+ e.srcElement.replaceWith(mermaidCode2);
1829
1851
  });
1830
1852
  document.body.appendChild(mermaidCode);
1831
1853
  }
@@ -76,11 +76,14 @@ module Brick::Rails::FormTags
76
76
  pk.map { |pk_part| obj.send(pk_part.to_sym) }), { class: 'big-arrow' })}</td>\n" if pk.present?
77
77
  sequence.each do |col_name|
78
78
  val = obj.attributes[col_name]
79
+ bt = bts[col_name]
79
80
  out << '<td'
80
- out << ' class=\"dimmed\"' unless cols.key?(col_name) || (cust_col = cust_cols[col_name]) ||
81
- (col_name.is_a?(Symbol) && bts.key?(col_name)) # HOT
81
+ (classes ||= []) << 'dimmed' unless cols.key?(col_name) || (cust_col = cust_cols[col_name]) ||
82
+ (col_name.is_a?(Symbol) && bts.key?(col_name)) # HOT
83
+ (classes ||= []) << 'right' if val.is_a?(Numeric) && !bt
84
+ out << " class=\"#{classes.join(' ')}\"" if classes&.present?
82
85
  out << '>'
83
- if (bt = bts[col_name] || composite_bt_names[col_name])
86
+ if (bt || composite_bt_names[col_name])
84
87
  if bt[2] # Polymorphic?
85
88
  if (poly_id = obj.send("#{bt.first}_id"))
86
89
  # Was: obj.send("#{bt.first}_type")
@@ -5,7 +5,7 @@ module Brick
5
5
  module VERSION
6
6
  MAJOR = 1
7
7
  MINOR = 0
8
- TINY = 132
8
+ TINY = 134
9
9
 
10
10
  # PRE is nil unless it's a pre-release (beta, RC, etc.)
11
11
  PRE = nil
@@ -62,7 +62,7 @@ module Brick
62
62
  dir = +"#{::Rails.root}/app"
63
63
  path[0..-2].each do |path_part|
64
64
  dir << "/#{path_part}"
65
- Dir.mkdir(dir) unless Dir.exists?(dir)
65
+ Dir.mkdir(dir) unless Dir.exist?(dir)
66
66
  end
67
67
  File.open("#{dir}/#{path.last}.rb", 'w') { |f| f.write code } unless code.blank?
68
68
  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.132
4
+ version: 1.0.134
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-19 00:00:00.000000000 Z
11
+ date: 2023-04-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord