brick 1.0.100 → 1.0.101
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/brick/extensions.rb +37 -19
- data/lib/brick/frameworks/rails/engine.rb +77 -22
- data/lib/brick/frameworks/rails/form_tags.rb +9 -7
- data/lib/brick/version_number.rb +1 -1
- data/lib/brick.rb +111 -52
- 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: eba38d653370b0cc3e98f2adc82d8c475854440745bd35caab9a9a4253fc152c
|
4
|
+
data.tar.gz: 18ca517b90266cf5db711040a7f40c8e848600135ef0a39ad91da9cd2a0b1c89
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 859f48999fb0e8d1010a701e29c9f0275f716b20f54b4348576f4dbff7f68da1eb83709a51a1a7acd7debaf4dc1f82e863048ef16cda6b5f59862246e0c50787
|
7
|
+
data.tar.gz: d93c3db79715f62705c0b8f2f5bd2640a2756e1fbcb6aa6a7cf017a18bc31fa5e98496ea41539611c149f84870f24596c105d146484519b7f040d2f36b25ce45
|
data/lib/brick/extensions.rb
CHANGED
@@ -446,8 +446,13 @@ module ActiveRecord
|
|
446
446
|
selects << if is_mysql
|
447
447
|
"`#{tbl_no_schema}`.`#{col_name}`#{col_alias}"
|
448
448
|
elsif is_postgres || is_mssql
|
449
|
-
# Postgres can not use DISTINCT with any columns that are XML
|
450
|
-
|
449
|
+
if is_distinct # Postgres can not use DISTINCT with any columns that are XML or JSON
|
450
|
+
cast_as_text = if Brick.relations[klass.table_name]&.[](:cols)&.[](col_name)&.first == 'json'
|
451
|
+
'::jsonb' # Convert JSON to JSONB
|
452
|
+
elsif Brick.relations[klass.table_name]&.[](:cols)&.[](col_name)&.first&.start_with?('xml')
|
453
|
+
'::text' # Convert XML to text
|
454
|
+
end
|
455
|
+
end
|
451
456
|
"\"#{tbl_no_schema}\".\"#{col_name}\"#{cast_as_text}#{col_alias}"
|
452
457
|
elsif col.type # Could be Sqlite or Oracle
|
453
458
|
if col_alias || !(/^[a-z0-9_]+$/ =~ col_name)
|
@@ -631,19 +636,26 @@ module ActiveRecord
|
|
631
636
|
through_sources.map do |a|
|
632
637
|
from_clause << "\n LEFT OUTER JOIN #{a.table_name} br_t#{idx += 1} "
|
633
638
|
from_clause << if (src_ref = a.source_reflection).macro == :belongs_to
|
634
|
-
|
635
|
-
# binding.pry unless nm
|
639
|
+
nm = hmt_assoc.source_reflection.inverse_of&.name
|
636
640
|
link_back << nm
|
637
641
|
"ON br_t#{idx}.id = br_t#{idx - 1}.#{a.foreign_key}"
|
638
642
|
elsif src_ref.options[:as]
|
639
643
|
"ON br_t#{idx}.#{src_ref.type} = '#{src_ref.active_record.name}'" + # "polymorphable_type"
|
640
644
|
" AND br_t#{idx}.#{src_ref.foreign_key} = br_t#{idx - 1}.id"
|
641
645
|
elsif src_ref.options[:source_type]
|
642
|
-
|
643
|
-
|
644
|
-
|
645
|
-
|
646
|
-
|
646
|
+
if a == hm.source_reflection
|
647
|
+
print "Skipping #{hm.name} --HMT-> #{hm.source_reflection.name} as it uses source_type in a way which is not yet supported"
|
648
|
+
nix << k
|
649
|
+
bail_out = true
|
650
|
+
break
|
651
|
+
# "ON br_t#{idx}.#{a.foreign_type} = '#{src_ref.options[:source_type]}' AND " \
|
652
|
+
# "br_t#{idx}.#{a.foreign_key} = br_t#{idx - 1}.id"
|
653
|
+
else # Works for HMT through a polymorphic HO
|
654
|
+
link_back << hmt_assoc.source_reflection.inverse_of&.name # Some polymorphic "_able" thing
|
655
|
+
"ON br_t#{idx - 1}.#{a.foreign_type} = '#{src_ref.options[:source_type]}' AND " \
|
656
|
+
"br_t#{idx - 1}.#{a.foreign_key} = br_t#{idx}.id"
|
657
|
+
end
|
658
|
+
else # Standard has_many or has_one
|
647
659
|
# binding.pry unless (
|
648
660
|
nm = hmt_assoc.source_reflection.inverse_of&.name
|
649
661
|
# )
|
@@ -706,12 +718,13 @@ module ActiveRecord
|
|
706
718
|
on_clause << "#{tbl_alias}.#{poly_type} = '#{name}'"
|
707
719
|
end
|
708
720
|
unless from_clause
|
721
|
+
tbl_nm = hm.macro == :has_and_belongs_to_many ? hm.join_table : hm.table_name
|
709
722
|
hm_table_name = if is_mysql
|
710
|
-
"`#{
|
723
|
+
"`#{tbl_nm}`"
|
711
724
|
elsif is_postgres || is_mssql
|
712
|
-
"\"#{(
|
725
|
+
"\"#{(tbl_nm).gsub('.', '"."')}\""
|
713
726
|
else
|
714
|
-
|
727
|
+
tbl_nm
|
715
728
|
end
|
716
729
|
end
|
717
730
|
group_bys = ::Brick.is_oracle || is_mssql ? hm_selects : (1..hm_selects.length).to_a
|
@@ -1390,8 +1403,8 @@ class Object
|
|
1390
1403
|
# (More information on https://docs.avohq.io/2.0/controllers.html)
|
1391
1404
|
controller_base = Avo::ResourcesController
|
1392
1405
|
end
|
1393
|
-
table_name = ActiveSupport::Inflector.underscore(plural_class_name)
|
1394
|
-
singular_table_name = ActiveSupport::Inflector.singularize(
|
1406
|
+
table_name = model&.table_name || ActiveSupport::Inflector.underscore(plural_class_name)
|
1407
|
+
singular_table_name = ActiveSupport::Inflector.singularize(ActiveSupport::Inflector.underscore(plural_class_name))
|
1395
1408
|
pk = model&._brick_primary_key(relations.fetch(table_name, nil))
|
1396
1409
|
is_postgres = ActiveRecord::Base.connection.adapter_name == 'PostgreSQL'
|
1397
1410
|
is_mysql = ActiveRecord::Base.connection.adapter_name == 'Mysql2'
|
@@ -1576,7 +1589,6 @@ class Object
|
|
1576
1589
|
order_by, _ = model._brick_calculate_ordering(ordering, true) # Don't do the txt part
|
1577
1590
|
|
1578
1591
|
ar_relation = ActiveRecord.version < Gem::Version.new('4') ? model.preload : model.all
|
1579
|
-
|
1580
1592
|
@_brick_params = ar_relation.brick_select(params, (selects ||= []), order_by,
|
1581
1593
|
translations = {},
|
1582
1594
|
join_array = ::Brick::JoinArray.new)
|
@@ -1592,12 +1604,13 @@ class Object
|
|
1592
1604
|
end
|
1593
1605
|
end
|
1594
1606
|
ar_select = ar_relation.respond_to?(:_select!) ? ar_relation.dup._select!(*selects, *counts) : ar_relation.select(selects + counts)
|
1595
|
-
instance_variable_set("@#{table_name.
|
1596
|
-
|
1607
|
+
instance_variable_set("@#{table_name.split('.').last}".to_sym, ar_select)
|
1608
|
+
table_name_no_schema = singular_table_name.pluralize
|
1609
|
+
if namespace && (idx = lookup_context.prefixes.index(table_name_no_schema))
|
1597
1610
|
lookup_context.prefixes[idx] = "#{namespace.name.underscore}/#{lookup_context.prefixes[idx]}"
|
1598
1611
|
end
|
1599
1612
|
@_brick_excl = session[:_brick_exclude]&.split(',')&.each_with_object([]) do |excl, s|
|
1600
|
-
if (excl_parts = excl.split('.')).first ==
|
1613
|
+
if (excl_parts = excl.split('.')).first == table_name_no_schema
|
1601
1614
|
s << excl_parts.last
|
1602
1615
|
end
|
1603
1616
|
end
|
@@ -1728,7 +1741,12 @@ class Object
|
|
1728
1741
|
val_part.gsub('^^sl^^', '/')
|
1729
1742
|
end
|
1730
1743
|
end
|
1731
|
-
|
1744
|
+
# Support friendly_id gem
|
1745
|
+
if Object.const_defined?('FriendlyId') && model.instance_variable_get(:@friendly_id_config)
|
1746
|
+
model.friendly.find(id.is_a?(Array) && id.length == 1 ? id.first : id)
|
1747
|
+
else
|
1748
|
+
model.find(id.is_a?(Array) && id.length == 1 ? id.first : id)
|
1749
|
+
end
|
1732
1750
|
end
|
1733
1751
|
end
|
1734
1752
|
|
@@ -197,7 +197,7 @@ function linkSchemas() {
|
|
197
197
|
class BrickTitle
|
198
198
|
def initialize(name, view_component)
|
199
199
|
@vc = view_component
|
200
|
-
@_name = name
|
200
|
+
@_name = name || ''
|
201
201
|
end
|
202
202
|
def to_s
|
203
203
|
@_name.html_safe + @vc.instance_variable_get(:@__vc_helpers)&.link_to_brick(nil,
|
@@ -313,10 +313,10 @@ function linkSchemas() {
|
|
313
313
|
end
|
314
314
|
|
315
315
|
if @_brick_model
|
316
|
-
pk = @_brick_model._brick_primary_key(::Brick.relations.fetch(@_brick_model
|
316
|
+
pk = @_brick_model._brick_primary_key(::Brick.relations.fetch((table_name = @_brick_model.table_name.split('.').last), nil))
|
317
317
|
obj_name = model_name.split('::').last.underscore
|
318
318
|
path_obj_name = @_brick_model._brick_index(:singular)
|
319
|
-
table_name
|
319
|
+
table_name ||= obj_name.pluralize
|
320
320
|
template_link = nil
|
321
321
|
bts, hms = ::Brick.get_bts_and_hms(@_brick_model) # This gets BT and HM and also has_many :through (HMT)
|
322
322
|
hms_columns = [] # Used for 'index'
|
@@ -346,13 +346,16 @@ function linkSchemas() {
|
|
346
346
|
end
|
347
347
|
case args.first
|
348
348
|
when 'index'
|
349
|
-
|
349
|
+
if !skip_klass_hms.key?(assoc_name.to_sym) && (
|
350
|
+
@_brick_model._br_hm_counts.key?(assoc_name) ||
|
351
|
+
@_brick_model._br_bt_descrip.key?(assoc_name) # Will end up here if it's a has_one
|
352
|
+
)
|
350
353
|
hm_entry = +"'#{hm_assoc.name}' => [#{assoc_name.inspect}, "
|
351
|
-
hm_entry << if hm_assoc.macro == :
|
354
|
+
hm_entry << if hm_assoc.macro == :has_one
|
355
|
+
'nil'
|
356
|
+
else # :has_many or :has_and_belongs_to_many
|
352
357
|
# Postgres column names are limited to 63 characters
|
353
358
|
"'" + "b_r_#{assoc_name}_ct"[0..62] + "'"
|
354
|
-
else # has_one
|
355
|
-
'nil'
|
356
359
|
end
|
357
360
|
hm_entry << ", #{path_keys(hm_assoc, hm_fk_name, pk).inspect}]"
|
358
361
|
hms_columns << hm_entry
|
@@ -564,10 +567,58 @@ def hide_bcrypt(val, max_len = 200)
|
|
564
567
|
'(hidden)'
|
565
568
|
else
|
566
569
|
if val.is_a?(String)
|
567
|
-
val =
|
570
|
+
if (val = val.dup.strip).length > max_len
|
571
|
+
if val[0] == '<' # Seems to be HTML?
|
572
|
+
cur_len = 0
|
573
|
+
cur_idx = 0
|
574
|
+
# Find which HTML tags we might be inside so we can apply ending tags to balance
|
575
|
+
element_name = nil
|
576
|
+
in_closing = nil
|
577
|
+
elements = []
|
578
|
+
val.each_char do |ch|
|
579
|
+
case ch
|
580
|
+
when '<'
|
581
|
+
element_name = +''
|
582
|
+
when '/' # First character of tag is '/'?
|
583
|
+
in_closing = true if element_name == ''
|
584
|
+
when '>'
|
585
|
+
if element_name
|
586
|
+
if in_closing
|
587
|
+
if (idx = elements.index { |tag| tag.downcase == element_name.downcase })
|
588
|
+
elements.delete_at(idx)
|
589
|
+
end
|
590
|
+
elsif (tag_name = element_name.split.first).present?
|
591
|
+
elements.unshift(tag_name)
|
592
|
+
end
|
593
|
+
element_name = nil
|
594
|
+
in_closing = nil
|
595
|
+
end
|
596
|
+
else
|
597
|
+
element_name << ch if element_name
|
598
|
+
end
|
599
|
+
cur_idx += 1
|
600
|
+
# Unless it's inside wickets then this is real text content, and see if we're at the limit
|
601
|
+
break if element_name.nil? && ((cur_len += 1) > max_len)
|
602
|
+
end
|
603
|
+
val = val[0..cur_idx]
|
604
|
+
# Somehow still in the middle of an opening tag right at the end? (Should never happen)
|
605
|
+
if !in_closing && (tag_name = element_name&.split&.first)&.present?
|
606
|
+
elements.unshift(tag_name)
|
607
|
+
val << '>'
|
608
|
+
end
|
609
|
+
elements.each do |closing_tag|
|
610
|
+
val << \"</#\{closing_tag}>\"
|
611
|
+
end
|
612
|
+
else # Not HTML, just cut it at the length
|
613
|
+
val = val[0...max_len]
|
614
|
+
end
|
615
|
+
val = \"#\{val}...\"
|
616
|
+
end
|
568
617
|
val = val.dup.force_encoding('UTF-8') unless val.encoding.name == 'UTF-8'
|
618
|
+
val
|
619
|
+
else
|
620
|
+
val.to_s
|
569
621
|
end
|
570
|
-
val
|
571
622
|
end
|
572
623
|
end
|
573
624
|
def display_value(col_type, val)
|
@@ -994,8 +1045,12 @@ erDiagram
|
|
994
1045
|
+"<html>
|
995
1046
|
<head>
|
996
1047
|
#{css}
|
997
|
-
<title
|
998
|
-
|
1048
|
+
<title><% model = #{model_name}
|
1049
|
+
if sub_model = @_brick_params&.fetch(type_col = model.inheritance_column, nil)&.first
|
1050
|
+
model = Object.const_get(sub_model.to_sym)
|
1051
|
+
end
|
1052
|
+
%><%= model.name %><%
|
1053
|
+
if (description = (relation = Brick.relations[model.table_name])&.fetch(:description, nil)).present?
|
999
1054
|
%> - <%= description
|
1000
1055
|
%><% end
|
1001
1056
|
%></title>
|
@@ -1005,15 +1060,15 @@ erDiagram
|
|
1005
1060
|
#{schema_options}" if schema_options}
|
1006
1061
|
<select id=\"tbl\">#{table_options}</select>
|
1007
1062
|
<table id=\"resourceName\"><tr>
|
1008
|
-
<td><h1
|
1063
|
+
<td><h1><%= model.name %></h1></td>
|
1009
1064
|
<td id=\"imgErd\" title=\"Show ERD\"></td>
|
1010
1065
|
<% if Object.const_defined?('Avo') && ::Avo.respond_to?(:railtie_namespace) %>
|
1011
1066
|
<td><%= link_to_brick(
|
1012
1067
|
avo_svg,
|
1013
|
-
{ index_proc: Proc.new do |
|
1014
|
-
::Avo.railtie_routes_url_helpers.send(\"resources_#\{model.
|
1068
|
+
{ index_proc: Proc.new do |avo_model|
|
1069
|
+
::Avo.railtie_routes_url_helpers.send(\"resources_#\{model.model_name.route_key}_path\".to_sym)
|
1015
1070
|
end,
|
1016
|
-
title:
|
1071
|
+
title: \"#\{model.name} in Avo\" }
|
1017
1072
|
) %></td>
|
1018
1073
|
<% end %>
|
1019
1074
|
</tr></table>#{template_link}<%
|
@@ -1025,13 +1080,13 @@ erDiagram
|
|
1025
1080
|
<% if @_brick_params.length == 1 # %%% Does not yet work with composite keys
|
1026
1081
|
k, id = @_brick_params.first
|
1027
1082
|
id = id.first if id.is_a?(Array) && id.length == 1
|
1028
|
-
origin = (key_parts = k.split('.')).length == 1 ?
|
1083
|
+
origin = (key_parts = k.split('.')).length == 1 ? model : model.reflect_on_association(key_parts.first).klass
|
1029
1084
|
if (destination_fk = Brick.relations[origin.table_name][:fks].values.find { |fk| fk[:fk] == key_parts.last }) &&
|
1030
1085
|
(obj = (destination = origin.reflect_on_association(destination_fk[:assoc_name])&.klass)&.find(id)) %>
|
1031
1086
|
<h3>for <%= link_to \"#{"#\{obj.brick_descrip\} (#\{destination.name\})\""}, send(\"#\{destination._brick_index(:singular)\}_path\".to_sym, id) %></h3><%
|
1032
1087
|
end
|
1033
1088
|
end %>
|
1034
|
-
(<%= link_to
|
1089
|
+
(<%= link_to \"See all #\{model.base_class.name.split('::').last.pluralize}\", #{@_brick_model._brick_index}_path %>)
|
1035
1090
|
<% end
|
1036
1091
|
# COLUMN EXCLUSIONS
|
1037
1092
|
if @_brick_excl&.present? %>
|
@@ -1058,10 +1113,10 @@ erDiagram
|
|
1058
1113
|
end.join(', ')}}
|
1059
1114
|
|
1060
1115
|
# If the resource is missing, has the user simply created an inappropriately pluralised name for a table?
|
1061
|
-
@#{table_name} ||= if dym_list = instance_variables.reject do |entry|
|
1062
|
-
|
1063
|
-
|
1064
|
-
|
1116
|
+
@#{table_name} ||= if (dym_list = instance_variables.reject do |entry|
|
1117
|
+
entry.to_s.start_with?('@_') ||
|
1118
|
+
['@cache_hit', '@marked_for_same_origin_verification', '@view_renderer', '@view_flow', '@output_buffer', '@virtual_path'].include?(entry.to_s)
|
1119
|
+
end).present?
|
1065
1120
|
msg = \"Can't find resource \\\"#{table_name}\\\".\"
|
1066
1121
|
# Can't be sure otherwise of what is up, so check DidYouMean and offer a suggestion.
|
1067
1122
|
if (dym = DidYouMean::SpellChecker.new(dictionary: dym_list).correct('@#{table_name}')).present?
|
@@ -1078,7 +1133,7 @@ erDiagram
|
|
1078
1133
|
|
1079
1134
|
# Write out the mega-grid
|
1080
1135
|
brick_grid(@#{table_name}, @_brick_bt_descrip, @_brick_sequence, @_brick_incl, @_brick_excl,
|
1081
|
-
|
1136
|
+
cols, poly_cols, bts, #{hms_keys.inspect}, {#{hms_columns.join(', ')}}) %>
|
1082
1137
|
|
1083
1138
|
#{"<hr><%= link_to \"New #{obj_name}\", new_#{path_obj_name}_path %>" unless @_brick_model.is_view?}
|
1084
1139
|
#{script}
|
@@ -11,7 +11,7 @@ module Brick::Rails::FormTags
|
|
11
11
|
out << "<th x-order=\"#{pk.join(',')}\"></th>"
|
12
12
|
end
|
13
13
|
|
14
|
-
col_keys
|
14
|
+
col_keys = relation.columns.each_with_object([]) do |col, s|
|
15
15
|
col_name = col.name
|
16
16
|
next if inclusions&.exclude?(col_name) ||
|
17
17
|
(pk.include?(col_name) && [:integer, :uuid].include?(col.type) && !bts.key?(col_name)) ||
|
@@ -39,8 +39,10 @@ module Brick::Rails::FormTags
|
|
39
39
|
"#{' x-order="' + col_name + '"' if true}>#{col_name}"
|
40
40
|
end
|
41
41
|
elsif col # HM column
|
42
|
+
options = {}
|
43
|
+
options[col[1].inheritance_column] = col[1].name unless col[1] == col[1].base_class
|
42
44
|
s << "<th#{' x-order="' + col_name + '"' if true}>#{col[2]} "
|
43
|
-
s << (col.first ? "#{col[3]}" : "#{link_to(col[3], send("#{col[1]._brick_index}_path"))}")
|
45
|
+
s << (col.first ? "#{col[3]}" : "#{link_to(col[3], send("#{col[1]._brick_index}_path", options))}")
|
44
46
|
elsif cust_cols.key?(col_name) # Custom column
|
45
47
|
s << "<th x-order=\"#{col_name}\">#{col_name}"
|
46
48
|
elsif col_name.is_a?(Symbol) && (hot = bts[col_name]) # has_one :through
|
@@ -96,17 +98,17 @@ module Brick::Rails::FormTags
|
|
96
98
|
if hms_col.length == 1
|
97
99
|
out << hms_col.first
|
98
100
|
else
|
99
|
-
|
101
|
+
hm_klass = (col = cols[col_name])[1]
|
100
102
|
if col[2] == 'HO'
|
101
|
-
descrips = bt_descrip[col_name.to_sym][
|
103
|
+
descrips = bt_descrip[col_name.to_sym][hm_klass]
|
102
104
|
if (ho_id = (ho_id_col = descrips.last).map { |id_col| obj.send(id_col.to_sym) })&.first
|
103
|
-
ho_txt =
|
104
|
-
out << link_to(ho_txt, send("#{
|
105
|
+
ho_txt = hm_klass.brick_descrip(obj, descrips[0..-2].map { |id| obj.send(id.last[0..62]) }, ho_id_col)
|
106
|
+
out << link_to(ho_txt, send("#{hm_klass.base_class._brick_index(:singular)}_path".to_sym, ho_id))
|
105
107
|
end
|
106
108
|
else
|
107
109
|
if (ct = obj.send(hms_col[1].to_sym)&.to_i)&.positive?
|
108
110
|
out << "#{link_to("#{ct || 'View'} #{hms_col.first}",
|
109
|
-
send("#{
|
111
|
+
send("#{hm_klass._brick_index}_path".to_sym,
|
110
112
|
hms_col[2].each_with_object({}) { |v, s| s[v.first] = v.last.is_a?(String) ? v.last : obj.send(v.last) })
|
111
113
|
)}\n"
|
112
114
|
end
|
data/lib/brick/version_number.rb
CHANGED
data/lib/brick.rb
CHANGED
@@ -640,50 +640,62 @@ In config/initializers/brick.rb appropriate entries would look something like:
|
|
640
640
|
table_class_length = 38 # Length of "Classes that can be built from tables:"
|
641
641
|
view_class_length = 37 # Length of "Classes that can be built from views:"
|
642
642
|
|
643
|
-
brick_routes_create = lambda do |schema_name,
|
643
|
+
brick_routes_create = lambda do |schema_name, res_name, options|
|
644
644
|
if schema_name # && !Object.const_defined('Apartment')
|
645
645
|
send(:namespace, schema_name) do
|
646
|
-
send(:resources,
|
646
|
+
send(:resources, res_name.to_sym, **options)
|
647
647
|
end
|
648
648
|
else
|
649
|
-
send(:resources,
|
649
|
+
send(:resources, res_name.to_sym, **options)
|
650
650
|
end
|
651
651
|
end
|
652
652
|
|
653
653
|
# %%% TODO: If no auto-controllers then enumerate the controllers folder in order to build matching routes
|
654
654
|
# If auto-controllers and auto-models are both enabled then this makes sense:
|
655
655
|
controller_prefix = (path_prefix ? "#{path_prefix}/" : '')
|
656
|
+
sti_subclasses = ::Brick.config.sti_namespace_prefixes.each_with_object(Hash.new { |h, k| h[k] = [] }) do |v, s|
|
657
|
+
# Turn something like {"::Spouse"=>"Person", "::Friend"=>"Person"} into {"Person"=>["Spouse", "Friend"]}
|
658
|
+
s[v.last] << v.first[2..-1] unless v.first.end_with?('::')
|
659
|
+
end
|
656
660
|
::Brick.relations.each do |k, v|
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
661
|
+
next if !(controller_name = v.fetch(:resource, nil)&.pluralize) || existing_controllers.key?(controller_name)
|
662
|
+
|
663
|
+
options = {}
|
664
|
+
options[:only] = [:index, :show] if v.key?(:isView)
|
665
|
+
# First do the API routes
|
666
|
+
full_resource = nil
|
667
|
+
if (schema_name = v.fetch(:schema, nil))
|
668
|
+
full_resource = "#{schema_name}/#{v[:resource]}"
|
669
|
+
send(:get, "#{::Brick.api_root}#{full_resource}", { to: "#{controller_prefix}#{schema_name}/#{controller_name}#index" }) if Object.const_defined?('Rswag::Ui')
|
670
|
+
else
|
671
|
+
# Normally goes to something like: /api/v1/employees
|
672
|
+
send(:get, "#{::Brick.api_root}#{v[:resource]}", { to: "#{controller_prefix}#{controller_name}#index" }) if Object.const_defined?('Rswag::Ui')
|
673
|
+
end
|
674
|
+
|
675
|
+
# Track routes being built
|
676
|
+
if (class_name = v.fetch(:class_name, nil))
|
677
|
+
if v.key?(:isView)
|
678
|
+
view_class_length = class_name.length if class_name.length > view_class_length
|
679
|
+
views
|
665
680
|
else
|
666
|
-
|
667
|
-
|
668
|
-
end
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
681
|
+
table_class_length = class_name.length if class_name.length > table_class_length
|
682
|
+
tables
|
683
|
+
end << [class_name, full_resource || v[:resource]]
|
684
|
+
end
|
685
|
+
|
686
|
+
# Now the normal routes
|
687
|
+
if path_prefix
|
688
|
+
# Was: send(:scope, path: path_prefix) do
|
689
|
+
send(:namespace, path_prefix) do
|
690
|
+
brick_routes_create.call(schema_name, v[:resource], options)
|
691
|
+
sti_subclasses.fetch(class_name, nil)&.each do |sc| # Add any STI subclass routes for this relation
|
692
|
+
brick_routes_create.call(schema_name, sc.underscore.tr('/', '_').pluralize, options)
|
674
693
|
end
|
675
|
-
else
|
676
|
-
brick_routes_create.call(schema_name, controller_name, v, options)
|
677
694
|
end
|
678
|
-
|
679
|
-
|
680
|
-
|
681
|
-
|
682
|
-
views
|
683
|
-
else
|
684
|
-
table_class_length = class_name.length if class_name.length > table_class_length
|
685
|
-
tables
|
686
|
-
end << [class_name, full_resource || v[:resource]]
|
695
|
+
else
|
696
|
+
brick_routes_create.call(schema_name, v[:resource], options)
|
697
|
+
sti_subclasses.fetch(class_name, nil)&.each do |sc| # Add any STI subclass routes for this relation
|
698
|
+
brick_routes_create.call(schema_name, sc.underscore.tr('/', '_').pluralize, options)
|
687
699
|
end
|
688
700
|
end
|
689
701
|
end
|
@@ -1322,24 +1334,26 @@ module ActiveRecord
|
|
1322
1334
|
private
|
1323
1335
|
|
1324
1336
|
# %%% Pretty much have to flat-out replace this guy (I think anyway)
|
1325
|
-
# Good with Rails 5.24
|
1326
|
-
|
1327
|
-
|
1328
|
-
associations
|
1329
|
-
|
1330
|
-
|
1331
|
-
|
1332
|
-
|
1333
|
-
|
1334
|
-
|
1335
|
-
|
1337
|
+
# Good with Rails 5.24 through 7 on this
|
1338
|
+
# Ransack gem includes Polyamorous which replaces #build in a different way (which we handle below)
|
1339
|
+
unless Gem::Specification.all_names.any? { |g| g.start_with?('ransack-') }
|
1340
|
+
def build(associations, base_klass, root = nil, path = '')
|
1341
|
+
root ||= associations
|
1342
|
+
associations.map do |name, right|
|
1343
|
+
reflection = find_reflection base_klass, name
|
1344
|
+
reflection.check_validity!
|
1345
|
+
reflection.check_eager_loadable!
|
1346
|
+
|
1347
|
+
if reflection.polymorphic?
|
1348
|
+
raise EagerLoadPolymorphicError.new(reflection)
|
1349
|
+
end
|
1336
1350
|
|
1337
|
-
|
1338
|
-
|
1339
|
-
|
1340
|
-
|
1341
|
-
|
1342
|
-
|
1351
|
+
link_path = path.blank? ? name.to_s : path + ".#{name}"
|
1352
|
+
ja = JoinAssociation.new(reflection, build(right, reflection.klass, root, link_path))
|
1353
|
+
ja.instance_variable_set(:@link_path, link_path) # Make note on the JoinAssociation of its AR path
|
1354
|
+
ja.instance_variable_set(:@assocs, root)
|
1355
|
+
ja
|
1356
|
+
end
|
1343
1357
|
end
|
1344
1358
|
end
|
1345
1359
|
|
@@ -1348,10 +1362,9 @@ module ActiveRecord
|
|
1348
1362
|
alias _brick_table_aliases_for table_aliases_for
|
1349
1363
|
def table_aliases_for(parent, node)
|
1350
1364
|
result = _brick_table_aliases_for(parent, node)
|
1351
|
-
|
1352
1365
|
# Capture the table alias name that was chosen
|
1353
|
-
link_path = node.instance_variable_get(:@link_path)
|
1354
1366
|
if (relation = node.instance_variable_get(:@assocs)&.instance_variable_get(:@relation))
|
1367
|
+
link_path = node.instance_variable_get(:@link_path)
|
1355
1368
|
relation.brick_links[link_path] = result.first.table_alias || result.first.table_name
|
1356
1369
|
end
|
1357
1370
|
result
|
@@ -1360,11 +1373,14 @@ module ActiveRecord
|
|
1360
1373
|
alias _brick_make_constraints make_constraints
|
1361
1374
|
def make_constraints(parent, child, join_type)
|
1362
1375
|
result = _brick_make_constraints(parent, child, join_type)
|
1363
|
-
|
1364
1376
|
# Capture the table alias name that was chosen
|
1365
|
-
link_path = child.instance_variable_get(:@link_path)
|
1366
1377
|
if (relation = child.instance_variable_get(:@assocs)&.instance_variable_get(:@relation))
|
1367
|
-
|
1378
|
+
link_path = child.instance_variable_get(:@link_path)
|
1379
|
+
relation.brick_links[link_path] = if child.table.is_a?(Arel::Nodes::TableAlias)
|
1380
|
+
child.table.right
|
1381
|
+
else
|
1382
|
+
result.first&.left&.table_alias || child.table_name
|
1383
|
+
end
|
1368
1384
|
end
|
1369
1385
|
result
|
1370
1386
|
end
|
@@ -1374,4 +1390,47 @@ module ActiveRecord
|
|
1374
1390
|
end
|
1375
1391
|
end
|
1376
1392
|
|
1393
|
+
# Now the Ransack Polyamorous version of #build
|
1394
|
+
if Gem::Specification.all_names.any? { |g| g.start_with?('ransack-') }
|
1395
|
+
require "polyamorous/activerecord_#{::ActiveRecord::VERSION::STRING[0, 3]}_ruby_2/join_dependency"
|
1396
|
+
module Polyamorous::JoinDependencyExtensions
|
1397
|
+
def build(associations, base_klass, root = nil, path = '')
|
1398
|
+
root ||= associations
|
1399
|
+
puts associations.map(&:first)
|
1400
|
+
|
1401
|
+
associations.map do |name, right|
|
1402
|
+
link_path = path.blank? ? name.to_s : path + ".#{name}"
|
1403
|
+
ja = if name.is_a? ::Polyamorous::Join
|
1404
|
+
reflection = find_reflection base_klass, name.name
|
1405
|
+
reflection.check_validity!
|
1406
|
+
reflection.check_eager_loadable!
|
1407
|
+
|
1408
|
+
klass = if reflection.polymorphic?
|
1409
|
+
name.klass || base_klass
|
1410
|
+
else
|
1411
|
+
reflection.klass
|
1412
|
+
end
|
1413
|
+
::ActiveRecord::Associations::JoinDependency::JoinAssociation.new(
|
1414
|
+
reflection, build(right, klass, root, link_path), name.klass, name.type
|
1415
|
+
)
|
1416
|
+
else
|
1417
|
+
reflection = find_reflection base_klass, name
|
1418
|
+
reflection.check_validity!
|
1419
|
+
reflection.check_eager_loadable!
|
1420
|
+
|
1421
|
+
if reflection.polymorphic?
|
1422
|
+
raise ActiveRecord::EagerLoadPolymorphicError.new(reflection)
|
1423
|
+
end
|
1424
|
+
::ActiveRecord::Associations::JoinDependency::JoinAssociation.new(
|
1425
|
+
reflection, build(right, reflection.klass, root, link_path)
|
1426
|
+
)
|
1427
|
+
end
|
1428
|
+
ja.instance_variable_set(:@link_path, link_path) # Make note on the JoinAssociation of its AR path
|
1429
|
+
ja.instance_variable_set(:@assocs, root)
|
1430
|
+
ja
|
1431
|
+
end
|
1432
|
+
end
|
1433
|
+
end
|
1434
|
+
end
|
1435
|
+
|
1377
1436
|
require 'brick/extensions'
|
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.101
|
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-12-
|
11
|
+
date: 2022-12-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|