brick 1.0.121 → 1.0.123

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 142adfa751be46ca1115b6e6f6945ab25ad10148e55c7584eba6f91be62c6cf0
4
- data.tar.gz: a20a11f7fc6c864fbf9c5d9b4c6f80f29c0d26380e0aa110b63183f6e0c2e3e0
3
+ metadata.gz: baad039242ee5623097ad6170fec07e5feb0eb2fed6d41a9079f0775cccaceea
4
+ data.tar.gz: 603377f6b2c4437c448630bce6581d3650b8dfc13187e82afbaab1d425d171e2
5
5
  SHA512:
6
- metadata.gz: 84c6880fcb0c2aa00ee7484053c40afc61e2f9e66af38bb677408f762002c8a990a2f68bd3f17443916e02ed1a08b1db605bc28a7e913b2841bbb1318a3dcca0
7
- data.tar.gz: 377decd3c088a4ddc6034de54aed3885e99b10e54a5336885a4b8ed1c611e52947af99728b48ffa6bb0b5ec29babf971dea580bcfca053deb4f5fb3f60fd1877
6
+ metadata.gz: 1f4e48c1a437684929a81ace3e75ab15bb627c006680dba5a7454825fba358142560712f016bf944575aefeb27655716c3212d72a2b9b5a083a09cd2dfa8537c
7
+ data.tar.gz: ea9c376866230e4c2bab7b6c34dfc435a8cf81b568bc22af3a0e69497accca1620152ae311eab6c96649b79ecedf978b880afa88888dc6d1c4d3700bc3ef3060
@@ -58,6 +58,16 @@ module ActiveRecord
58
58
  def is_view?
59
59
  false
60
60
  end
61
+
62
+ def real_model(params)
63
+ if params && (sub_model = params.fetch(type_col = inheritance_column, nil))
64
+ sub_model = sub_model.first if sub_model.is_a?(Array) # Support the params style that gets returned from #brick_select
65
+ # Make sure the chosen model is really the same or a subclass of this model
66
+ (possible_model = sub_model.constantize) <= self ? possible_model : self
67
+ else
68
+ self
69
+ end
70
+ end
61
71
  end
62
72
 
63
73
  def self._brick_primary_key(relation = nil)
@@ -1651,16 +1661,18 @@ class Object
1651
1661
  return
1652
1662
  end
1653
1663
 
1664
+ real_model = model.real_model(params)
1665
+
1654
1666
  if request.format == :csv # Asking for a template?
1655
1667
  require 'csv'
1656
1668
  exported_csv = CSV.generate(force_quotes: false) do |csv_out|
1657
- model.df_export(model.brick_import_template).each { |row| csv_out << row }
1669
+ real_model.df_export(real_model.brick_import_template).each { |row| csv_out << row }
1658
1670
  end
1659
1671
  render inline: exported_csv, content_type: request.format
1660
1672
  return
1661
1673
  # elsif request.format == :js || current_api_root # Asking for JSON?
1662
1674
  # # %%% Add: where, order, page, page_size, offset, limit
1663
- # data = (model.is_view? || !Object.const_defined?('DutyFree')) ? model.limit(1000) : model.df_export(model.brick_import_template)
1675
+ # data = (real_model.is_view? || !Object.const_defined?('DutyFree')) ? real_model.limit(1000) : real_model.df_export(real_model.brick_import_template)
1664
1676
  # render inline: { data: data }.to_json, content_type: request.format == '*/*' ? 'application/json' : request.format
1665
1677
  # return
1666
1678
  end
@@ -1670,9 +1682,9 @@ class Object
1670
1682
  # %%% Allow params to define which columns to use for order_by
1671
1683
  # Overriding the default by providing a querystring param?
1672
1684
  ordering = params['_brick_order']&.split(',')&.map(&:to_sym) || Object.send(:default_ordering, table_name, pk)
1673
- order_by, _ = model._brick_calculate_ordering(ordering, true) # Don't do the txt part
1685
+ order_by, _ = real_model._brick_calculate_ordering(ordering, true) # Don't do the txt part
1674
1686
 
1675
- ar_relation = ActiveRecord.version < Gem::Version.new('4') ? model.preload : model.all
1687
+ ar_relation = ActiveRecord.version < Gem::Version.new('4') ? real_model.preload : real_model.all
1676
1688
  params['_brick_is_api'] = true if (is_api = request.format == :js || current_api_root)
1677
1689
  @_brick_params = ar_relation.brick_select(params, (selects ||= []), order_by,
1678
1690
  translations = {},
@@ -1682,7 +1694,7 @@ class Object
1682
1694
  # Apply column renaming
1683
1695
  data = ar_relation.respond_to?(:_select!) ? ar_relation.dup._select!(*selects) : ar_relation.select(selects)
1684
1696
  if data.present? &&
1685
- (column_renaming = ::Brick.find_col_renaming(current_api_root, model&._brick_relation)&.select { |cr| cr.last })
1697
+ (column_renaming = ::Brick.find_col_renaming(current_api_root, real_model&._brick_relation)&.select { |cr| cr.last })
1686
1698
  data.map!({}) do |row, s|
1687
1699
  column_renaming.each_with_object({}) do |rename, s|
1688
1700
  s[rename.last] = row[rename.first] if rename.last
@@ -1693,7 +1705,7 @@ class Object
1693
1705
  # # %%% This currently only gives a window to check security and raise an exception if someone isn't
1694
1706
  # # authenticated / authorised. Still need to figure out column filtering and transformations.
1695
1707
  # proc_result = if (column_filter = ::Brick.config.api_column_filter).is_a?(Proc)
1696
- # object_columns = (relation = model&._brick_relation)[:cols]
1708
+ # object_columns = (relation = real_model&._brick_relation)[:cols]
1697
1709
  # begin
1698
1710
  # num_args = column_filter.arity.negative? ? 5 : column_filter.arity
1699
1711
  # # object_name, api_version, columns, data
@@ -1718,7 +1730,7 @@ class Object
1718
1730
 
1719
1731
  # %%% Add custom HM count columns
1720
1732
  # %%% What happens when the PK is composite?
1721
- counts = model._br_hm_counts.each_with_object([]) do |v, s|
1733
+ counts = real_model._br_hm_counts.each_with_object([]) do |v, s|
1722
1734
  s << if is_mysql
1723
1735
  "`b_r_#{v.first}`.c_t_ AS \"b_r_#{v.first}_ct\""
1724
1736
  elsif is_postgres
@@ -1738,8 +1750,8 @@ class Object
1738
1750
  s << excl_parts.last
1739
1751
  end
1740
1752
  end
1741
- @_brick_bt_descrip = model._br_bt_descrip
1742
- @_brick_hm_counts = model._br_hm_counts
1753
+ @_brick_bt_descrip = real_model._br_bt_descrip
1754
+ @_brick_hm_counts = real_model._br_hm_counts
1743
1755
  @_brick_join_array = join_array
1744
1756
  @_brick_erd = params['_brick_erd']&.to_i
1745
1757
  end
@@ -1847,18 +1859,27 @@ class Object
1847
1859
  instance_variable_set("@#{singular_table_name}".to_sym, (obj = find_obj))
1848
1860
  upd_params = send(params_name_sym)
1849
1861
  json_overrides = ::Brick.config.json_columns&.fetch(table_name, nil)
1850
- if (json_cols = model.columns.select { |c| c.type == :json || json_overrides&.include?(c.name) }.map(&:name)).present?
1862
+ if model.respond_to?(:devise_modules)
1851
1863
  upd_hash = upd_params.to_h
1864
+ upd_hash['reset_password_token'] = nil if upd_hash['reset_password_token'].blank?
1865
+ upd_hash['reset_password_sent_at'] = nil if upd_hash['reset_password_sent_at'].blank?
1866
+ if model.devise_modules.include?(:invitable)
1867
+ upd_hash['invitation_token'] = nil if upd_hash['invitation_token'].blank?
1868
+ upd_hash['invitation_created_at'] = nil if upd_hash['invitation_created_at'].blank?
1869
+ upd_hash['invitation_sent_at'] = nil if upd_hash['invitation_sent_at'].blank?
1870
+ upd_hash['invitation_accepted_at'] = nil if upd_hash['invitation_accepted_at'].blank?
1871
+ end
1872
+ end
1873
+ if (json_cols = model.columns.select { |c| c.type == :json || json_overrides&.include?(c.name) }.map(&:name)).present?
1874
+ upd_hash ||= upd_params.to_h
1852
1875
  json_cols.each do |c|
1853
1876
  begin
1854
1877
  upd_hash[c] = JSON.parse(upd_hash[c].tr('`', '"').gsub('^^br_btick__', '`'))
1855
1878
  rescue
1856
1879
  end
1857
1880
  end
1858
- obj.send(:update, upd_hash)
1859
- else
1860
- obj.send(:update, upd_params)
1861
1881
  end
1882
+ obj.send(:update, upd_hash || upd_params)
1862
1883
  end
1863
1884
 
1864
1885
  code << " def destroy\n"
@@ -1894,10 +1915,11 @@ class Object
1894
1915
  end
1895
1916
  end
1896
1917
  # Support friendly_id gem
1918
+ id_simplified = id.is_a?(Array) && id.length == 1 ? id.first : id
1897
1919
  if Object.const_defined?('FriendlyId') && model.instance_variable_get(:@friendly_id_config)
1898
- model.friendly.find(id.is_a?(Array) && id.length == 1 ? id.first : id)
1920
+ model.friendly.find(id_simplified)
1899
1921
  else
1900
- model.find(id.is_a?(Array) && id.length == 1 ? id.first : id)
1922
+ model.find(id_simplified)
1901
1923
  end
1902
1924
  end
1903
1925
  end
@@ -2032,8 +2054,18 @@ end.class_exec do
2032
2054
  load inflections
2033
2055
  end
2034
2056
  # Now the Brick initializer since there may be important schema things configured
2035
- if File.exist?(brick_initializer = ::Rails.root.join('config/initializers/brick.rb'))
2057
+ if !::Brick.initializer_loaded && File.exist?(brick_initializer = ::Rails.root.join('config/initializers/brick.rb'))
2036
2058
  ::Brick.initializer_loaded = load brick_initializer
2059
+
2060
+ # After loading the initializer, add compatibility for ActiveStorage and ActionText if those haven't already been
2061
+ # defined. (Further JSON configuration for ActiveStorage metadata happens later in the after_initialize hook.)
2062
+ ['ActiveStorage', 'ActionText'].each do |ar_extension|
2063
+ if Object.const_defined?(ar_extension) &&
2064
+ (extension = Object.const_get(ar_extension)).respond_to?(:table_name_prefix) &&
2065
+ !::Brick.config.table_name_prefixes.key?(as_tnp = extension.table_name_prefix)
2066
+ ::Brick.config.table_name_prefixes[as_tnp] = ar_extension
2067
+ end
2068
+ end
2037
2069
  end
2038
2070
  # Load the initializer for the Apartment gem a little early so that if .excluded_models and
2039
2071
  # .default_schema are specified then we can work with non-tenanted models more appropriately
@@ -188,6 +188,17 @@ function linkSchemas() {
188
188
  (app.config.assets.paths ||= []) << assets_path
189
189
  end
190
190
 
191
+ # Treat ActiveStorage::Blob metadata as JSON
192
+ if ::Brick.config.table_name_prefixes.fetch('active_storage_', nil) == 'ActiveStorage' &&
193
+ ActiveStorage.const_defined?('Blob')
194
+ unless (md = (::Brick.config.model_descrips ||= {})).key?('ActiveStorage::Blob')
195
+ md['ActiveStorage::Blob'] = '[filename]'
196
+ end
197
+ unless (asbm = (::Brick.config.json_columns['active_storage_blobs'] ||= [])).include?('metadata')
198
+ asbm << 'metadata'
199
+ end
200
+ end
201
+
191
202
  # Smarten up Avo so it recognises Brick's querystring option for Apartment multi-tenancy
192
203
  if Object.const_defined?('Avo') && ::Avo.respond_to?(:railtie_namespace)
193
204
  module ::Avo
@@ -510,6 +521,16 @@ window.addEventListener(\"popstate\", linkSchemas);
510
521
  # Dynamically create generic templates
511
522
  # ====================================
512
523
  if ::Brick.enable_views?
524
+ # Add the params to the lookup_context so that we have context about STI classes when setting @_brick_model
525
+ ActionView::ViewPaths.class_exec do
526
+ alias :_brick_lookup_context :lookup_context
527
+ def lookup_context(*args)
528
+ ret = _brick_lookup_context(*args)
529
+ @_lookup_context.instance_variable_set(:@_brick_req_params, params)
530
+ ret
531
+ end
532
+ end
533
+
513
534
  ActionView::LookupContext.class_exec do
514
535
  # Used by Rails 5.0 and above
515
536
  alias :_brick_template_exists? :template_exists?
@@ -520,10 +541,10 @@ window.addEventListener(\"popstate\", linkSchemas);
520
541
  _brick_template_exists?(*args, **options) ||
521
542
  # Do not auto-create a template when it's searching for an application.html.erb, which comes in like: ["edit", ["games", "application"]]
522
543
  ((args[1].length == 1 || args[1][-1] != 'application') &&
523
- set_brick_model(args))
544
+ set_brick_model(args, @_brick_req_params))
524
545
  end
525
546
 
526
- def set_brick_model(find_args)
547
+ def set_brick_model(find_args, params)
527
548
  # Return an appropriate model for a given view template request.
528
549
  # find_args will generally be something like: ["index", ["categories"]]
529
550
  # and must cycle through all of find_args[1] because in some cases such as with Devise we get something like:
@@ -537,7 +558,7 @@ window.addEventListener(\"popstate\", linkSchemas);
537
558
  # Only CUD stuff has create / update / destroy
538
559
  (!model.is_view? && ['new', 'create', 'edit', 'update', 'destroy'].include?(find_args.first))
539
560
  )
540
- @_brick_model = model
561
+ @_brick_model = model.real_model(params)
541
562
  end
542
563
  rescue
543
564
  end
@@ -576,10 +597,14 @@ window.addEventListener(\"popstate\", linkSchemas);
576
597
  return possible_template
577
598
  end
578
599
  rescue StandardError => e
579
- find_template_err = e # Can come up with stuff like Devise which has its own view templates
600
+ # Search through the routes to confirm that something might match (Devise stuff for instance, which has its own view templates),
601
+ # and bubble the same exception (probably an ActionView::MissingTemplate) if a legitimate option is found.
602
+ raise if ::Rails.application.routes.set.find { |x| args[1].include?(x.defaults[:controller]) && args[0] == x.defaults[:action] }
603
+
604
+ find_template_err = e
580
605
  end
581
606
  # Used to also have: ActionView.version < ::Gem::Version.new('5.0') &&
582
- model_name = set_brick_model(args)&.name
607
+ model_name = set_brick_model(args, @_brick_req_params)&.name
583
608
  end
584
609
 
585
610
  if @_brick_model
@@ -636,7 +661,7 @@ window.addEventListener(\"popstate\", linkSchemas);
636
661
  (hm_fk_name.is_a?(String) && hm_fk_name.include?('.')) # HMT? (Could do a better check for this)
637
662
  predicates = path_keys(hm_assoc, hm_fk_name, pk).map do |k, v|
638
663
  if v == '[sti_type]'
639
- "'#{k}': @#{obj_name}.#{hm_assoc.active_record.inheritance_column}"
664
+ "'#{k}': (@#{obj_name}.#{hm_assoc.active_record.inheritance_column}).constantize.base_class.name"
640
665
  else
641
666
  v.is_a?(String) ? "'#{k}': '#{v}'" : "'#{k}': @#{obj_name}.#{v}"
642
667
  end
@@ -848,6 +873,10 @@ input+svg.revert {
848
873
  color: #FFF;
849
874
  }
850
875
  </style>
876
+ <script>
877
+ if (window.history.state && window.history.state.turbo)
878
+ window.addEventListener(\"popstate\", function () { location.reload(true); });
879
+ </script>
851
880
 
852
881
  <% is_includes_dates = nil
853
882
  is_includes_json = nil
@@ -1158,7 +1187,7 @@ erDiagram
1158
1187
  @_brick_bt_descrip&.each do |bt|
1159
1188
  bt_class = bt[1].first.first
1160
1189
  callbacks[bt_name = bt_class.name.split('::').last] = bt_class
1161
- is_has_one = #{@_brick_model.name}.reflect_on_association(bt.first).inverse_of&.macro == :has_one ||
1190
+ is_has_one = #{@_brick_model.name}.reflect_on_association(bt.first)&.inverse_of&.macro == :has_one ||
1162
1191
  ::Brick.config.has_ones&.fetch('#{@_brick_model.name}', nil)&.key?(bt.first.to_s)
1163
1192
  %> <%= \"#\{model_short_name} #\{is_has_one ? '||' : '}o'}--|| #\{bt_name} : \\\"#\{
1164
1193
  bt_underscored = bt[1].first.first.name.underscore.singularize
@@ -1316,13 +1345,9 @@ erDiagram
1316
1345
  +"<html>
1317
1346
  <head>
1318
1347
  #{css}
1319
- <title><% model = #{model_name}
1320
- if sub_model = @_brick_params&.fetch(type_col = model.inheritance_column, nil)&.first
1321
- model = Object.const_get(sub_model.to_sym)
1322
- end
1323
- %><%= model.name %><%
1324
- if (description = (relation = Brick.relations[model.table_name])&.fetch(:description, nil)).present?
1325
- %> - <%= description
1348
+ <title><%= (model = #{model_name}).name %><%
1349
+ if (description = (relation = Brick.relations[model.table_name])&.fetch(:description, nil)).present?
1350
+ %> - <%= description
1326
1351
  %><% end
1327
1352
  %></title>
1328
1353
  </head>
@@ -1359,7 +1384,27 @@ erDiagram
1359
1384
  ) %></td>
1360
1385
  <% end
1361
1386
  end %>
1362
- </tr><%= if (page_num = @#{table_name}._brick_page_num)
1387
+ </tr>
1388
+
1389
+ <%= if model < (base_model = model.base_class)
1390
+ this_model = model
1391
+ parent_links = []
1392
+ until this_model == base_model do
1393
+ this_model = this_model.superclass
1394
+ path = send(\"#\{this_model._brick_index}_path\")
1395
+ path << \"?#\{base_model.inheritance_column}=#\{this_model.name}\" unless this_model == base_model
1396
+ parent_links << link_to(this_model.name, path)
1397
+ end
1398
+ \"<tr><td colspan=\\\"#\{td_count}\\\">Parent: #\{parent_links.join(' ')}</tr>\".html_safe
1399
+ end
1400
+ %><%= if (children = model.descendants).present?
1401
+ child_links = children.map do |child|
1402
+ path = send(\"#\{child._brick_index}_path\") + \"?#\{base_model.inheritance_column}=#\{child.name}\"
1403
+ link_to(child.name, path)
1404
+ end
1405
+ \"<tr><td colspan=\\\"#\{td_count}\\\">Children: #\{child_links.join(' ')}</tr>\".html_safe
1406
+ end
1407
+ %><%= if (page_num = @#{table_name}._brick_page_num)
1363
1408
  \"<tr><td colspan=\\\"#\{td_count}\\\">Page #\{page_num}</td></tr>\".html_safe
1364
1409
  end %></table>#{template_link}<%
1365
1410
  if description.present? %><%=
@@ -1521,8 +1566,12 @@ erDiagram
1521
1566
  <head>
1522
1567
  #{css}
1523
1568
  <title><%=
1524
- model = (obj = @#{obj_name})&.class
1525
- model_name = @#{obj_name}.#{inh_col = @_brick_model.inheritance_column} if obj.respond_to?(:#{inh_col})
1569
+ base_model = (model = (obj = @#{obj_name})&.class).base_class
1570
+ see_all_path = send(\"#\{base_model._brick_index}_path\")
1571
+ if obj.respond_to?(:#{inh_col = @_brick_model.inheritance_column}) &&
1572
+ (model_name = @#{obj_name}.#{inh_col}) != base_model.name
1573
+ see_all_path << \"?#{inh_col}=#\{model_name}\"
1574
+ end
1526
1575
  page_title = (\"#\{model_name ||= model.name}: #\{obj&.brick_descrip || controller_name}\")
1527
1576
  %></title>
1528
1577
  </head>
@@ -1566,7 +1615,7 @@ erDiagram
1566
1615
  if (description = (relation = Brick.relations[tbl_name = #{model_name}.table_name])&.fetch(:description, nil)) %><%=
1567
1616
  description %><br><%
1568
1617
  end
1569
- %><%= link_to '(See all #{obj_name.pluralize})', #{@_brick_model._brick_index}_path %>
1618
+ %><%= link_to \"(See all #\{model_name.pluralize})\", see_all_path %>
1570
1619
  #{erd_markup}
1571
1620
  <% if obj
1572
1621
  # path_options = [obj.#{pk}]
@@ -1582,11 +1631,11 @@ end
1582
1631
  <%= form_for(obj.becomes(#{model_name}), options) do |f| %>
1583
1632
  <table class=\"shadow\">
1584
1633
  <% has_fields = false
1585
- @#{obj_name}.attributes.each do |k, val|
1586
- col = #{model_name}.columns_hash[k] %>
1587
- <tr>
1588
- <% next if (#{(pk || []).inspect}.include?(k) && !bts.key?(k)) ||
1634
+ @#{obj_name}.attributes.each do |k, val|
1635
+ next if !(col = #{model_name}.columns_hash[k]) ||
1636
+ (#{(pk || []).inspect}.include?(k) && !bts.key?(k)) ||
1589
1637
  ::Brick.config.metadata_columns.include?(k) %>
1638
+ <tr>
1590
1639
  <th class=\"show-field\"<%= \" title=\\\"#\{col.comment}\\\"\".html_safe if col.respond_to?(:comment) && !col.comment.blank? %>>
1591
1640
  <% has_fields = true
1592
1641
  if (bt = bts[k])
@@ -1650,9 +1699,13 @@ end
1650
1699
  if is_bcrypt?(val) # || .readonly?
1651
1700
  is_revert = false %>
1652
1701
  <%= hide_bcrypt(val, nil, 1000) %>
1653
- <% elsif col_type == :string %>
1654
- <%= f.text_field(k.to_sym, html_options) %>
1655
- <% else
1702
+ <% elsif col_type == :string
1703
+ if model.respond_to?(:enumerized_attributes) && (opts = model.enumerized_attributes[k]&.options).present? %>
1704
+ <%= f.select(k.to_sym, [[\"(No #\{k} chosen)\", '^^^brick_NULL^^^']] + opts, { value: val || '^^^brick_NULL^^^' }, html_options) %><%
1705
+ else %>
1706
+ <%= f.text_field(k.to_sym, html_options) %><%
1707
+ end
1708
+ else
1656
1709
  is_includes_text = true %>
1657
1710
  <%= f.hidden_field(k.to_sym, html_options) %>
1658
1711
  <trix-editor input=\"<%= f.field_id(k) %>\"></trix-editor>
@@ -86,19 +86,13 @@ module Brick::Rails::FormTags
86
86
  elsif descrips.length == 1
87
87
  [obj.class.reflect_on_association(bt.first)&.foreign_key]
88
88
  else
89
- # Was: descrips.last -- but the ID stuff is not coming through anymore
90
- [bt.first]
89
+ descrips.last
91
90
  end
92
- txt_parts = descrips.map do |id|
93
- obj2 = obj
94
- id[0..-2].each { |ref| obj2 = obj2&.send(ref) }
91
+ bt_txt = bt_class.brick_descrip(
95
92
  # 0..62 because Postgres column names are limited to 63 characters
96
- obj2&.send(id.last[0..62])
97
- end
98
- unless txt_parts.compact.empty?
99
- bt_txt = bt_class.brick_descrip(obj, txt_parts, bt_id_col)
100
- bt_txt = ::Brick::Rails.display_binary(bt_txt).html_safe if bt_txt&.encoding&.name == 'ASCII-8BIT'
101
- end
93
+ obj, descrips[0..-2].map { |id| obj.send(id.last[0..62]) }, bt_id_col
94
+ )
95
+ bt_txt = ::Brick::Rails.display_binary(bt_txt).html_safe if bt_txt&.encoding&.name == 'ASCII-8BIT'
102
96
  bt_txt ||= "<span class=\"orphan\">&lt;&lt; Orphaned ID: #{val} >></span>" if val
103
97
  bt_id = bt_id_col&.map { |id_col| obj.respond_to?(id_sym = id_col.to_sym) ? obj.send(id_sym) : id_col }
104
98
  out << (bt_id&.first ? link_to(bt_txt, send("#{bt_class.base_class._brick_index(:singular)}_path".to_sym, bt_id)) : bt_txt || '')
@@ -110,16 +104,16 @@ module Brick::Rails::FormTags
110
104
  hm_klass = (col = cols[col_name])[1]
111
105
  if col[2] == 'HO'
112
106
  descrips = bt_descrip[col_name.to_sym][hm_klass]
113
- if (ho_id = (ho_id_col = descrips.last).map { |id_col| obj.respond_to?(id_sym = id_col.to_sym) && obj.send(id_sym) })&.first
107
+ if (ho_id = (ho_id_col = descrips.last).map { |id_col| obj.send(id_col.to_sym) })&.first
114
108
  ho_txt = hm_klass.brick_descrip(obj, descrips[0..-2].map { |id| obj.send(id.last[0..62]) }, ho_id_col)
115
109
  out << link_to(ho_txt, send("#{hm_klass.base_class._brick_index(:singular)}_path".to_sym, ho_id))
116
110
  end
117
111
  else
118
112
  if (ct = obj.send(hms_col[1].to_sym)&.to_i)&.positive?
113
+ predicates = hms_col[2].each_with_object({}) { |v, s| s[v.first] = v.last.is_a?(String) ? v.last : obj.send(v.last) }
114
+ predicates.each { |k, v| predicates[k] = obj.class.name if v == '[sti_type]' }
119
115
  out << "#{link_to("#{ct || 'View'} #{hms_col.first}",
120
- send("#{hm_klass._brick_index}_path".to_sym,
121
- hms_col[2].each_with_object({}) { |v, s| s[v.first] = v.last.is_a?(String) ? v.last : obj.send(v.last) })
122
- )}\n"
116
+ send("#{hm_klass._brick_index}_path".to_sym, predicates))}\n"
123
117
  end
124
118
  end
125
119
  end
@@ -5,7 +5,7 @@ module Brick
5
5
  module VERSION
6
6
  MAJOR = 1
7
7
  MINOR = 0
8
- TINY = 121
8
+ TINY = 123
9
9
 
10
10
  # PRE is nil unless it's a pre-release (beta, RC, etc.)
11
11
  PRE = nil
data/lib/brick.rb CHANGED
@@ -1618,8 +1618,8 @@ module ActiveRecord
1618
1618
  end
1619
1619
  end
1620
1620
 
1621
- if JoinDependency.private_instance_methods.include?(:table_aliases_for)
1622
- # No matter if it's older or newer Rails, now extend so that we can associate AR links to table_alias names
1621
+ # No matter if it's older or newer Rails, now extend so that we can associate AR links to table_alias names
1622
+ if ActiveRecord.version < ::Gem::Version.new('6.1')
1623
1623
  alias _brick_table_aliases_for table_aliases_for
1624
1624
  def table_aliases_for(parent, node)
1625
1625
  result = _brick_table_aliases_for(parent, node)
@@ -1630,7 +1630,7 @@ module ActiveRecord
1630
1630
  end
1631
1631
  result
1632
1632
  end
1633
- else # Same idea but for Rails 7
1633
+ else # Same idea but for Rails >= 6.1
1634
1634
  alias _brick_make_constraints make_constraints
1635
1635
  def make_constraints(parent, child, join_type)
1636
1636
  result = _brick_make_constraints(parent, child, join_type)
@@ -1657,7 +1657,7 @@ if Gem::Specification.all_names.any? { |g| g.start_with?('ransack-') }
1657
1657
  module Polyamorous::JoinDependencyExtensions
1658
1658
  def build(associations, base_klass, root = nil, path = '')
1659
1659
  root ||= associations
1660
- puts associations.map(&:first)
1660
+ # puts associations.map(&:first)
1661
1661
 
1662
1662
  associations.map do |name, right|
1663
1663
  link_path = path.blank? ? name.to_s : path + ".#{name}"
@@ -1694,6 +1694,29 @@ if Gem::Specification.all_names.any? { |g| g.start_with?('ransack-') }
1694
1694
  end
1695
1695
  end
1696
1696
 
1697
+ # Patch Enumerize so that #becomes works when an STI subclass is becoming a base class
1698
+ # which does not include Enumerize.
1699
+ # (See https://github.com/brainspec/enumerize/issues/426)
1700
+ if Object.const_defined?('Enumerize') && Enumerize.const_defined?('ActiveRecordSupport')
1701
+ Enumerize::ActiveRecordSupport::InstanceMethods.class_exec do
1702
+ def becomes(klass)
1703
+ became = super
1704
+ klass = self.class unless klass.respond_to?(:enumerized_attributes)
1705
+ klass.enumerized_attributes.each do |attr|
1706
+ begin
1707
+ if became.respond_to?(setter = "#{attr.name}=")
1708
+ became.send(setter, send(attr.name))
1709
+ end
1710
+ rescue ActiveModel::MissingAttributeError
1711
+ rescue ActiveRecord::SerializationTypeMismatch
1712
+ became.send(setter, send(attr.name).to_ary)
1713
+ end
1714
+ end
1715
+ became
1716
+ end
1717
+ end
1718
+ end
1719
+
1697
1720
  # Keyword arguments updates for Rails <= 5.2.x and Ruby >= 3.0
1698
1721
  if ActiveRecord.version < ::Gem::Version.new('6.0') && ruby_version >= ::Gem::Version.new('3.0')
1699
1722
  admsm = ActionDispatch::MiddlewareStack::Middleware
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.121
4
+ version: 1.0.123
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-03-19 00:00:00.000000000 Z
11
+ date: 2023-03-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord