brick 1.0.84 → 1.0.86
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/brick/compatibility.rb +20 -5
- data/lib/brick/config.rb +25 -4
- data/lib/brick/extensions.rb +48 -19
- data/lib/brick/frameworks/rails/controller.rb +10 -4
- data/lib/brick/frameworks/rails/engine.rb +43 -14
- data/lib/brick/util.rb +1 -0
- data/lib/brick/version_number.rb +1 -1
- data/lib/brick.rb +52 -21
- data/lib/generators/brick/install_generator.rb +8 -2
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 67cdd41b9c4a3a235e4d88a151149a7c2c9345a4280efe31c3fbd983b65fbdd4
|
4
|
+
data.tar.gz: 12f80d33a0360cfa67fb703ed59b65b9216cafa07a18d9283baf9df584067896
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e95aefd208502dfa2ae724d178a29d15ccad4d00522ecbb865019823ba331c0d9f6e4026aea1b634f57f1d7945d8f522e35361d42d9de972698de91c0b9bd129
|
7
|
+
data.tar.gz: 99d0df87ae591bf836f6040aa237863fb1535774cb6fae515bb1c25edd284b4f37d5a1c01584138df81cfbb66a535ef8bec9aaf2550c96a42c02dee7e48aada1
|
data/lib/brick/compatibility.rb
CHANGED
@@ -10,12 +10,27 @@ unless ActiveRecord.respond_to?(:version)
|
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
module ActionView
|
13
|
+
# ActiveSupport, ActionPack, and ActionView before 4.0 didn't have #version
|
14
|
+
unless ActiveSupport.respond_to?(:version)
|
15
|
+
module ActiveSupport
|
17
16
|
def self.version
|
18
|
-
|
17
|
+
::Gem::Version.new(ActiveSupport::VERSION::STRING)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
if Object.const_defined?('ActionPack')
|
22
|
+
unless ActionPack.respond_to?(:version)
|
23
|
+
module ActionPack
|
24
|
+
def self.version
|
25
|
+
::Gem::Version.new(ActionPack::VERSION::STRING)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
if Object.const_defined?('ActionView') && !ActionView.respond_to?(:version)
|
30
|
+
module ActionView
|
31
|
+
def self.version
|
32
|
+
ActionPack.version
|
33
|
+
end
|
19
34
|
end
|
20
35
|
end
|
21
36
|
end
|
data/lib/brick/config.rb
CHANGED
@@ -20,6 +20,23 @@ module Brick
|
|
20
20
|
@serializer = Brick::Serializers::YAML
|
21
21
|
end
|
22
22
|
|
23
|
+
def mode
|
24
|
+
@mutex.synchronize do
|
25
|
+
case @brick_mode
|
26
|
+
when nil, :development
|
27
|
+
(::Rails.env == 'development' || ENV.key?('BRICK')) ? :on : nil
|
28
|
+
when :diag_env
|
29
|
+
ENV.key?('BRICK') ? :on : nil
|
30
|
+
else
|
31
|
+
@brick_mode
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def mode=(setting)
|
37
|
+
@mutex.synchronize { @brick_mode = setting unless @brick_mode == :on }
|
38
|
+
end
|
39
|
+
|
23
40
|
# Any path prefixing to apply to all auto-generated Brick routes
|
24
41
|
def path_prefix
|
25
42
|
@mutex.synchronize { @path_prefix }
|
@@ -31,7 +48,8 @@ module Brick
|
|
31
48
|
|
32
49
|
# Indicates whether Brick models are on or off. Default: true.
|
33
50
|
def enable_models
|
34
|
-
|
51
|
+
brick_mode = mode
|
52
|
+
@mutex.synchronize { brick_mode == :on && (@enable_models.nil? || @enable_models) }
|
35
53
|
end
|
36
54
|
|
37
55
|
def enable_models=(enable)
|
@@ -40,7 +58,8 @@ module Brick
|
|
40
58
|
|
41
59
|
# Indicates whether Brick controllers are on or off. Default: true.
|
42
60
|
def enable_controllers
|
43
|
-
|
61
|
+
brick_mode = mode
|
62
|
+
@mutex.synchronize { brick_mode == :on && (@enable_controllers.nil? || @enable_controllers) }
|
44
63
|
end
|
45
64
|
|
46
65
|
def enable_controllers=(enable)
|
@@ -49,7 +68,8 @@ module Brick
|
|
49
68
|
|
50
69
|
# Indicates whether Brick views are on or off. Default: true.
|
51
70
|
def enable_views
|
52
|
-
|
71
|
+
brick_mode = mode
|
72
|
+
@mutex.synchronize { brick_mode == :on && (@enable_views.nil? || @enable_views) }
|
53
73
|
end
|
54
74
|
|
55
75
|
def enable_views=(enable)
|
@@ -58,7 +78,8 @@ module Brick
|
|
58
78
|
|
59
79
|
# Indicates whether Brick routes are on or off. Default: true.
|
60
80
|
def enable_routes
|
61
|
-
|
81
|
+
brick_mode = mode
|
82
|
+
@mutex.synchronize { brick_mode == :on && (@enable_routes.nil? || @enable_routes) }
|
62
83
|
end
|
63
84
|
|
64
85
|
def enable_routes=(enable)
|
data/lib/brick/extensions.rb
CHANGED
@@ -239,7 +239,7 @@ module ActiveRecord
|
|
239
239
|
pk_alias = [pk_alias] unless pk_alias.is_a?(Array)
|
240
240
|
id = []
|
241
241
|
pk_alias.each do |pk_alias_part|
|
242
|
-
if (pk_part = obj.send(pk_alias_part))
|
242
|
+
if (pk_part = obj.respond_to?(pk_alias_part) ? obj.send(pk_alias_part) : nil)
|
243
243
|
id << pk_part
|
244
244
|
end
|
245
245
|
end
|
@@ -608,7 +608,11 @@ module ActiveRecord
|
|
608
608
|
# %%% Need to support {user: :profile}
|
609
609
|
next unless assoc_name.is_a?(Symbol)
|
610
610
|
|
611
|
-
table_alias =
|
611
|
+
table_alias = if (chain = chains[klass = reflect_on_association(assoc_name)&.klass])
|
612
|
+
shift_or_first(chain)
|
613
|
+
else
|
614
|
+
klass.table_name # ActiveRecord < 4.2 can't (yet) use the cool chains thing
|
615
|
+
end
|
612
616
|
_assoc_names[assoc_name] = [table_alias, klass]
|
613
617
|
end
|
614
618
|
end
|
@@ -706,7 +710,7 @@ module ActiveRecord
|
|
706
710
|
join_clause = "LEFT OUTER
|
707
711
|
JOIN (SELECT #{hm_selects.map { |s| "#{'br_t0.' if from_clause}#{s}" }.join(', ')}, COUNT(#{'DISTINCT ' if hm.options[:through]}#{count_column
|
708
712
|
}) AS c_t_ FROM #{from_clause || hm_table_name} GROUP BY #{group_bys.join(', ')}) #{tbl_alias}"
|
709
|
-
|
713
|
+
self.joins_values |= ["#{join_clause} ON #{on_clause.join(' AND ')}"] # Same as: joins!(...)
|
710
714
|
end
|
711
715
|
while (n = nix.pop)
|
712
716
|
klass._br_hm_counts.delete(n)
|
@@ -723,7 +727,11 @@ JOIN (SELECT #{hm_selects.map { |s| "#{'br_t0.' if from_clause}#{s}" }.join(', '
|
|
723
727
|
s["#{tbl_name}.#{v_parts.last}"] = v.last
|
724
728
|
end
|
725
729
|
end
|
726
|
-
where!
|
730
|
+
if respond_to?(:where!)
|
731
|
+
where!(wheres2)
|
732
|
+
else # AR < 4.0
|
733
|
+
self.where_values << build_where(wheres2)
|
734
|
+
end
|
727
735
|
end
|
728
736
|
# Must parse the order_by and see if there are any symbols which refer to BT associations
|
729
737
|
# or custom columns as they must be expanded to find the corresponding b_r_model__column
|
@@ -747,9 +755,10 @@ JOIN (SELECT #{hm_selects.map { |s| "#{'br_t0.' if from_clause}#{s}" }.join(', '
|
|
747
755
|
selects << v if is_distinct
|
748
756
|
end
|
749
757
|
end
|
750
|
-
order!(*final_order_by)
|
758
|
+
self.order_values |= final_order_by # Same as: order!(*final_order_by)
|
751
759
|
end
|
752
|
-
|
760
|
+
# Don't want to get too carried away just yet
|
761
|
+
self.limit_value = 1000 # Same as: limit!(1000)
|
753
762
|
wheres unless wheres.empty? # Return the specific parameters that we did use
|
754
763
|
end
|
755
764
|
|
@@ -766,7 +775,7 @@ JOIN (SELECT #{hm_selects.map { |s| "#{'br_t0.' if from_clause}#{s}" }.join(', '
|
|
766
775
|
|
767
776
|
alias _brick_find_sti_class find_sti_class
|
768
777
|
def find_sti_class(type_name)
|
769
|
-
if ::Brick.sti_models.key?(type_name)
|
778
|
+
if ::Brick.sti_models.key?(type_name ||= name)
|
770
779
|
_brick_find_sti_class(type_name)
|
771
780
|
else
|
772
781
|
# This auto-STI is more of a brute-force approach, building modules where needed
|
@@ -816,6 +825,8 @@ end
|
|
816
825
|
if Object.const_defined?('ActionView')
|
817
826
|
module ActionView::Helpers::FormTagHelper
|
818
827
|
def link_to_brick(*args, **kwargs)
|
828
|
+
return unless ::Brick.config.mode == :on
|
829
|
+
|
819
830
|
text = (args.first.is_a?(String) && args.first) || args[1]
|
820
831
|
klass_or_obj = ((args.first.is_a?(ActiveRecord::Relation) ||
|
821
832
|
args.first.is_a?(ActiveRecord::Base) ||
|
@@ -860,7 +871,7 @@ if Object.const_defined?('ActionView')
|
|
860
871
|
pk = (klass.primary_key || ActiveRecord::Base.primary_key).to_sym
|
861
872
|
# Used to also have this but it's a bit too permissive to identify a primary key: (path_params.length == 1 && path_params.values.first) ||
|
862
873
|
if ((id = (path_params[pk] || path_params[:id] || path_params["#{klass.name.underscore}_id".to_sym])) && (obj = klass.find_by(pk => id))) ||
|
863
|
-
(['show', 'edit'].include?(action_name) && (obj = klass.first))
|
874
|
+
(['show', 'edit', 'update', 'destroy'].include?(action_name) && (obj = klass.first))
|
864
875
|
obj
|
865
876
|
else
|
866
877
|
# %%% If there is a HMT that refers to some ___id then try to identify an appropriate filter
|
@@ -933,8 +944,13 @@ if ActiveSupport::Dependencies.respond_to?(:autoload_module!) # %%% Only works w
|
|
933
944
|
autoloaded_constants << qualified_name unless autoloaded_constants.include?(qualified_name)
|
934
945
|
klass
|
935
946
|
elsif (base_class = ::Brick.config.sti_namespace_prefixes&.fetch("::#{const_name}", nil)&.constantize)
|
936
|
-
|
937
|
-
|
947
|
+
begin
|
948
|
+
# Attempt to find an existing implementation for this subclass
|
949
|
+
base_class.module_parent.const_get(const_name)
|
950
|
+
rescue
|
951
|
+
# Build subclass and place it in the same module as its parent
|
952
|
+
base_class.module_parent.const_set(const_name.to_sym, klass = Class.new(base_class))
|
953
|
+
end
|
938
954
|
else
|
939
955
|
_brick_autoload_module!(*args)
|
940
956
|
end
|
@@ -1507,9 +1523,10 @@ class Object
|
|
1507
1523
|
ordering = params['_brick_order']&.split(',')&.map(&:to_sym) || Object.send(:default_ordering, table_name, pk)
|
1508
1524
|
order_by, _ = model._brick_calculate_ordering(ordering, true) # Don't do the txt part
|
1509
1525
|
|
1510
|
-
|
1511
|
-
|
1512
|
-
|
1526
|
+
ar_relation = ActiveRecord.version < Gem::Version.new('4') ? model.preload : model.all
|
1527
|
+
@_brick_params = ar_relation.brick_select(params, (selects = []), order_by,
|
1528
|
+
translations = {},
|
1529
|
+
join_array = ::Brick::JoinArray.new)
|
1513
1530
|
# %%% Add custom HM count columns
|
1514
1531
|
# %%% What happens when the PK is composite?
|
1515
1532
|
counts = model._br_hm_counts.each_with_object([]) do |v, s|
|
@@ -1521,7 +1538,8 @@ class Object
|
|
1521
1538
|
"b_r_#{v.first}.c_t_ AS \"b_r_#{v.first}_ct\""
|
1522
1539
|
end
|
1523
1540
|
end
|
1524
|
-
|
1541
|
+
ar_select = ar_relation.respond_to?(:_select!) ? ar_relation.dup._select!(*selects, *counts) : ar_relation.select(selects + counts)
|
1542
|
+
instance_variable_set("@#{table_name.pluralize}".to_sym, ar_select)
|
1525
1543
|
if namespace && (idx = lookup_context.prefixes.index(table_name))
|
1526
1544
|
lookup_context.prefixes[idx] = "#{namespace.name.underscore}/#{lookup_context.prefixes[idx]}"
|
1527
1545
|
end
|
@@ -1633,7 +1651,11 @@ class Object
|
|
1633
1651
|
code << " end\n"
|
1634
1652
|
self.define_method :destroy do
|
1635
1653
|
::Brick.set_db_schema(params)
|
1636
|
-
|
1654
|
+
if (obj = find_obj).send(:destroy)
|
1655
|
+
redirect_to send("#{model._brick_index}_path".to_sym)
|
1656
|
+
else
|
1657
|
+
redirect_to send("#{model._brick_index(:singular)}_path".to_sym, obj)
|
1658
|
+
end
|
1637
1659
|
end
|
1638
1660
|
end
|
1639
1661
|
|
@@ -1732,10 +1754,16 @@ end
|
|
1732
1754
|
# Get info on all relations during first database connection
|
1733
1755
|
# ==========================================================
|
1734
1756
|
|
1735
|
-
|
1757
|
+
if ActiveRecord.const_defined?('ConnectionHandling')
|
1758
|
+
ActiveRecord::ConnectionHandling
|
1759
|
+
else
|
1760
|
+
ActiveRecord::ConnectionAdapters::ConnectionHandler
|
1761
|
+
end.class_exec do
|
1736
1762
|
alias _brick_establish_connection establish_connection
|
1737
1763
|
def establish_connection(*args)
|
1738
1764
|
conn = _brick_establish_connection(*args)
|
1765
|
+
return conn unless ::Brick.config.mode == :on
|
1766
|
+
|
1739
1767
|
begin
|
1740
1768
|
# Overwrite SQLite's #begin_db_transaction so it opens in IMMEDIATE mode instead of
|
1741
1769
|
# the default DEFERRED mode.
|
@@ -1866,7 +1894,7 @@ module ActiveRecord::ConnectionHandling
|
|
1866
1894
|
case ActiveRecord::Base.connection.adapter_name
|
1867
1895
|
when 'PostgreSQL', 'SQLite' # These bring back a hash for each row because the query uses column aliases
|
1868
1896
|
# schema ||= 'public' if ActiveRecord::Base.connection.adapter_name == 'PostgreSQL'
|
1869
|
-
|
1897
|
+
retrieve_schema_and_tables(sql, is_postgres, is_mssql, schema).each do |r|
|
1870
1898
|
# If Apartment gem lists the table as being associated with a non-tenanted model then use whatever it thinks
|
1871
1899
|
# is the default schema, usually 'public'.
|
1872
1900
|
schema_name = if ::Brick.config.schema_behavior[:multitenant]
|
@@ -1915,7 +1943,7 @@ WHERE c.owner IN (#{::Brick.db_schemas.keys.map { |s| "'#{s}'" }.join(', ')})
|
|
1915
1943
|
ORDER BY 1, 2, c.internal_column_id, acc.position"
|
1916
1944
|
ActiveRecord::Base.execute_sql(sql, *ar_tables)
|
1917
1945
|
else
|
1918
|
-
|
1946
|
+
retrieve_schema_and_tables(sql)
|
1919
1947
|
end
|
1920
1948
|
|
1921
1949
|
schema_and_tables.each do |r|
|
@@ -2016,6 +2044,7 @@ ORDER BY 1, 2, c.internal_column_id, acc.position"
|
|
2016
2044
|
end
|
2017
2045
|
::Brick.is_oracle = true if ActiveRecord::Base.connection.adapter_name == 'OracleEnhanced'
|
2018
2046
|
# ::Brick.default_schema ||= schema ||= 'public' if ActiveRecord::Base.connection.adapter_name == 'PostgreSQL'
|
2047
|
+
::Brick.default_schema ||= 'public' if ActiveRecord::Base.connection.adapter_name == 'PostgreSQL'
|
2019
2048
|
fk_references&.each do |fk|
|
2020
2049
|
fk = fk.values unless fk.is_a?(Array)
|
2021
2050
|
# Multitenancy makes things a little more general overall, except for non-tenanted tables
|
@@ -2113,7 +2142,7 @@ ORDER BY 1, 2, c.internal_column_id, acc.position"
|
|
2113
2142
|
else
|
2114
2143
|
'schema_migrations'
|
2115
2144
|
end
|
2116
|
-
ar_imtn = ActiveRecord.version >= ::Gem::Version.new('5.0') ? ActiveRecord::Base.internal_metadata_table_name : ''
|
2145
|
+
ar_imtn = ActiveRecord.version >= ::Gem::Version.new('5.0') ? ActiveRecord::Base.internal_metadata_table_name : 'ar_internal_metadata'
|
2117
2146
|
[ar_smtn, ar_imtn]
|
2118
2147
|
end
|
2119
2148
|
|
@@ -8,10 +8,16 @@ module Brick
|
|
8
8
|
# `brick_enabled_for_controller`.
|
9
9
|
module Controller
|
10
10
|
def self.included(controller)
|
11
|
-
controller.before_action
|
12
|
-
|
13
|
-
|
14
|
-
|
11
|
+
if controller.respond_to?(:before_action)
|
12
|
+
controller.before_action(
|
13
|
+
:set_brick_enabled_for_controller,
|
14
|
+
:set_brick_controller_info
|
15
|
+
)
|
16
|
+
else
|
17
|
+
controller.before_filter(
|
18
|
+
:set_brick_enabled_for_controller,
|
19
|
+
:set_brick_controller_info
|
20
|
+
)
|
15
21
|
end
|
16
22
|
|
17
23
|
protected
|
@@ -103,12 +103,18 @@ module Brick
|
|
103
103
|
unless (model_name = @_brick_model&.name) ||
|
104
104
|
(is_status = ::Brick.config.add_status && args[0..1] == ['status', ['brick_gem']]) ||
|
105
105
|
(is_orphans = ::Brick.config.add_orphans && args[0..1] == ['orphans', ['brick_gem']])
|
106
|
-
if
|
106
|
+
if ActionView.version < ::Gem::Version.new('5.0') # %%% Not sure if this should be perhaps 4.2 instead
|
107
|
+
begin
|
108
|
+
if (possible_template = _brick_find_template(*args, **options))
|
109
|
+
return possible_template
|
110
|
+
end
|
111
|
+
rescue
|
112
|
+
end
|
113
|
+
elsif (possible_template = _brick_find_template(*args, **options))
|
107
114
|
return possible_template
|
108
|
-
else
|
109
|
-
# Used to also have: ActionView.version < ::Gem::Version.new('5.0') &&
|
110
|
-
model_name = (args[1].is_a?(Array) ? set_brick_model(args) : nil)&.name
|
111
115
|
end
|
116
|
+
# Used to also have: ActionView.version < ::Gem::Version.new('5.0') &&
|
117
|
+
model_name = (args[1].is_a?(Array) ? set_brick_model(args) : nil)&.name
|
112
118
|
end
|
113
119
|
|
114
120
|
if @_brick_model
|
@@ -154,7 +160,7 @@ module Brick
|
|
154
160
|
'nil'
|
155
161
|
else
|
156
162
|
# Postgres column names are limited to 63 characters
|
157
|
-
"#{obj_name}.#{"b_r_#{assoc_name}_ct"[0..62]} || 0"
|
163
|
+
"#{obj_name}.#{"b_r_#{assoc_name}_ct"[0..62]}&.to_i || 0"
|
158
164
|
end
|
159
165
|
", #{set_ct}, #{path_keys(hm_assoc, hm_fk_name, obj_name, pk)}"
|
160
166
|
end
|
@@ -181,10 +187,15 @@ module Brick
|
|
181
187
|
end
|
182
188
|
end
|
183
189
|
|
184
|
-
|
190
|
+
apartment_default_schema = ::Brick.apartment_multitenant && Apartment.default_schema
|
191
|
+
schema_options = if ::Brick.apartment_multitenant &&
|
192
|
+
(cur_schema = Apartment::Tenant.current) != apartment_default_schema
|
193
|
+
"<option selected value=\"#{cur_schema}\">#{cur_schema}</option>"
|
194
|
+
else
|
195
|
+
::Brick.db_schemas.keys.each_with_object(+'') { |v, s| s << "<option value=\"#{v}\">#{v}</option>" }
|
196
|
+
end.html_safe
|
185
197
|
# %%% If we are not auto-creating controllers (or routes) then omit by default, and if enabled anyway, such as in a development
|
186
198
|
# environment or whatever, then get either the controllers or routes list instead
|
187
|
-
apartment_default_schema = ::Brick.apartment_multitenant && Apartment.default_schema
|
188
199
|
prefix = "#{::Brick.config.path_prefix}/" if ::Brick.config.path_prefix
|
189
200
|
table_options = (::Brick.relations.keys - ::Brick.config.exclude_tables).each_with_object({}) do |tbl, s|
|
190
201
|
binding.pry if tbl.is_a?(Symbol)
|
@@ -329,6 +340,10 @@ a.big-arrow {
|
|
329
340
|
color: red;
|
330
341
|
white-space: nowrap;
|
331
342
|
}
|
343
|
+
.danger {
|
344
|
+
background-color: red;
|
345
|
+
color: white;
|
346
|
+
}
|
332
347
|
|
333
348
|
#revertTemplate {
|
334
349
|
display: none;
|
@@ -446,7 +461,7 @@ var #{table_name}HtColumns;
|
|
446
461
|
// This PageTransitionEvent fires when the page first loads, as well as after any other history
|
447
462
|
// transition such as when using the browser's Back and Forward buttons.
|
448
463
|
window.addEventListener(\"pageshow\", function() {
|
449
|
-
if (schemaSelect) { // First drop-down is only present if multitenant
|
464
|
+
if (schemaSelect && schemaSelect.options.length > 1) { // First drop-down is only present if multitenant
|
450
465
|
brickSchema = changeout(location.href, \"_brick_schema\");
|
451
466
|
if (brickSchema) {
|
452
467
|
[... document.getElementsByTagName(\"A\")].forEach(function (a) { a.href = changeout(a.href, \"_brick_schema\", brickSchema); });
|
@@ -910,12 +925,19 @@ erDiagram
|
|
910
925
|
%><%= link_to(\"#\{bt_class} ##\{poly_id}\", send(\"#\{base_class_underscored}_path\".to_sym, poly_id)) if poly_id %><%
|
911
926
|
else
|
912
927
|
# binding.pry if @_brick_bt_descrip[bt.first][bt[1].first.first].nil?
|
913
|
-
|
928
|
+
bt_class = bt[1].first.first
|
929
|
+
descrips = @_brick_bt_descrip[bt.first][bt_class]
|
930
|
+
bt_id_col = if descrips.length == 1
|
931
|
+
[#{obj_name}.class.reflect_on_association(bt.first)&.foreign_key]
|
932
|
+
else
|
933
|
+
descrips.last
|
934
|
+
end
|
935
|
+
bt_txt = bt_class.brick_descrip(
|
914
936
|
# 0..62 because Postgres column names are limited to 63 characters
|
915
|
-
#{obj_name},
|
937
|
+
#{obj_name}, descrips[0..-2].map { |id| #{obj_name}.send(id.last[0..62]) }, bt_id_col
|
916
938
|
)
|
917
939
|
bt_txt ||= \"<span class=\\\"orphan\\\"><< Orphaned ID: #\{val} >></span>\".html_safe if val
|
918
|
-
bt_id = bt_id_col
|
940
|
+
bt_id = bt_id_col&.map { |id_col| #{obj_name}.respond_to?(id_sym = id_col.to_sym) ? #{obj_name}.send(id_sym) : id_col } %>
|
919
941
|
<%= bt_id&.first ? link_to(bt_txt, send(\"#\{bt_class.base_class._brick_index(:singular)}_path\".to_sym, bt_id)) : bt_txt %>
|
920
942
|
<% end
|
921
943
|
elsif (hms_col = hms_cols[col_name])
|
@@ -1163,6 +1185,7 @@ end
|
|
1163
1185
|
<% end %>
|
1164
1186
|
|
1165
1187
|
#{unless args.first == 'new'
|
1188
|
+
confirm_are_you_sure = ActionView.version < ::Gem::Version.new('7.0') ? "data: { confirm: 'Are you sure?' }" : "form: { data: { turbo_confirm: 'Are you sure?' } }"
|
1166
1189
|
hms_headers.each_with_object(+'') do |hm, s|
|
1167
1190
|
# %%% Would be able to remove this when multiple foreign keys to same destination becomes bulletproof
|
1168
1191
|
next if hm.first.options[:through] && !hm.first.through_reflection
|
@@ -1173,7 +1196,7 @@ end
|
|
1173
1196
|
s << "<table id=\"#{hm_name}\" class=\"shadow\">
|
1174
1197
|
<tr><th>#{hm[3]}</th></tr>
|
1175
1198
|
<% collection = @#{obj_name}.#{hm_name}
|
1176
|
-
collection = collection.is_a?(ActiveRecord::Associations::CollectionProxy) ? collection.order(#{pk.inspect}) :
|
1199
|
+
collection = collection.is_a?(ActiveRecord::Associations::CollectionProxy) ? collection.order(#{pk.inspect}) : collection.to_a.compact
|
1177
1200
|
if collection.empty? %>
|
1178
1201
|
<tr><td>(none)</td></tr>
|
1179
1202
|
<% else %>
|
@@ -1185,7 +1208,8 @@ end
|
|
1185
1208
|
else
|
1186
1209
|
s
|
1187
1210
|
end
|
1188
|
-
end
|
1211
|
+
end +
|
1212
|
+
"<%= 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} }) %>"
|
1189
1213
|
end}
|
1190
1214
|
<% end %>
|
1191
1215
|
#{script}"
|
@@ -1193,7 +1217,7 @@ end}
|
|
1193
1217
|
end
|
1194
1218
|
inline << "
|
1195
1219
|
<% if is_includes_dates %>
|
1196
|
-
<link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/npm/flatpickr/dist/flatpickr.min.css\">
|
1220
|
+
<link rel=\"stylesheet\" type=\"text/css\" href=\"https://cdn.jsdelivr.net/npm/flatpickr/dist/flatpickr.min.css\">
|
1197
1221
|
<style>
|
1198
1222
|
.flatpickr-calendar {
|
1199
1223
|
background: #A0FFA0;
|
@@ -1207,6 +1231,11 @@ flatpickr(\".timepicker\", {enableTime: true, noCalendar: true});
|
|
1207
1231
|
</script>
|
1208
1232
|
<% end %>
|
1209
1233
|
|
1234
|
+
<% if false # is_includes_dropdowns %>
|
1235
|
+
<script src=\"https://cdnjs.cloudflare.com/ajax/libs/slim-select/1.27.1/slimselect.min.js\"></script>
|
1236
|
+
<link rel=\"stylesheet\" type=\"text/css\" href=\"https://cdnjs.cloudflare.com/ajax/libs/slim-select/1.27.1/slimselect.min.css\">
|
1237
|
+
<% end %>
|
1238
|
+
|
1210
1239
|
<% if true # @_brick_erd
|
1211
1240
|
%>
|
1212
1241
|
<script>
|
data/lib/brick/util.rb
CHANGED
@@ -84,6 +84,7 @@ module Brick
|
|
84
84
|
|
85
85
|
def self._custom_require_dir
|
86
86
|
unless (custom_require_dir = ::Brick::Util.instance_variable_get(:@_custom_require_dir))
|
87
|
+
require 'tmpdir'
|
87
88
|
::Brick::Util.instance_variable_set(:@_custom_require_dir, (custom_require_dir = Dir.mktmpdir))
|
88
89
|
# So normal Ruby require will now pick this one up
|
89
90
|
$LOAD_PATH.unshift(custom_require_dir)
|
data/lib/brick/version_number.rb
CHANGED
data/lib/brick.rb
CHANGED
@@ -26,27 +26,38 @@ end
|
|
26
26
|
require 'brick/util'
|
27
27
|
|
28
28
|
# Allow ActiveRecord < 3.2 to work with Ruby 2.7 and later
|
29
|
-
if (ruby_version = ::Gem::Version.new(RUBY_VERSION)) >= ::Gem::Version.new('2.7')
|
30
|
-
|
31
|
-
|
32
|
-
::Brick::Util._patch_require(
|
33
|
-
'active_support/values/time_zone.rb', '/activesupport',
|
34
|
-
[' def parse(str, now=now)',
|
35
|
-
' def parse(str, now=now())']
|
36
|
-
)
|
37
|
-
# Remove circular reference for "reflection" for ActiveRecord 3.1
|
38
|
-
if ActiveRecord.version >= ::Gem::Version.new('3.1')
|
29
|
+
if (ruby_version = ::Gem::Version.new(RUBY_VERSION)) >= ::Gem::Version.new('2.7')
|
30
|
+
if ActiveRecord.version < ::Gem::Version.new('3.2')
|
31
|
+
# Remove circular reference for "now"
|
39
32
|
::Brick::Util._patch_require(
|
40
|
-
'
|
41
|
-
['
|
42
|
-
|
43
|
-
:HasManyAssociation # Make sure the path for this guy is available to be autoloaded
|
33
|
+
'active_support/values/time_zone.rb', '/activesupport',
|
34
|
+
[' def parse(str, now=now)',
|
35
|
+
' def parse(str, now=now())']
|
44
36
|
)
|
37
|
+
# Remove circular reference for "reflection" for ActiveRecord 3.1
|
38
|
+
if ActiveRecord.version >= ::Gem::Version.new('3.1')
|
39
|
+
::Brick::Util._patch_require(
|
40
|
+
'active_record/associations/has_many_association.rb', '/activerecord',
|
41
|
+
['reflection = reflection)',
|
42
|
+
'reflection = reflection())'],
|
43
|
+
:HasManyAssociation # Make sure the path for this guy is available to be autoloaded
|
44
|
+
)
|
45
|
+
end
|
45
46
|
end
|
47
|
+
|
48
|
+
# # Create unfrozen route path in Rails 3.2
|
49
|
+
# if ActiveRecord.version < ::Gem::Version.new('4')
|
50
|
+
# ::Brick::Util._patch_require(
|
51
|
+
# 'action_dispatch/routing/route_set.rb', '/actiondispatch',
|
52
|
+
# ["script_name.chomp('/')).to_s",
|
53
|
+
# "script_name.chomp('/')).to_s.dup"],
|
54
|
+
# :RouteSet # Make sure the path for this guy is available to be autoloaded
|
55
|
+
# )
|
56
|
+
# end
|
46
57
|
end
|
47
58
|
|
48
59
|
# Add left_outer_join! to Associations::JoinDependency and Relation::QueryMethods
|
49
|
-
if ActiveRecord.version < ::Gem::Version.new('5')
|
60
|
+
if ActiveRecord.version >= ::Gem::Version.new('4') && ActiveRecord.version < ::Gem::Version.new('5')
|
50
61
|
::Brick::Util._patch_require(
|
51
62
|
'active_record/associations/join_dependency.rb', '/activerecord', # /associations
|
52
63
|
["def join_constraints(outer_joins)
|
@@ -126,7 +137,7 @@ module Brick
|
|
126
137
|
|
127
138
|
def set_db_schema(params = nil)
|
128
139
|
schema = (params ? params['_brick_schema'] : ::Brick.default_schema)
|
129
|
-
if schema && ::Brick.db_schemas&.key?(schema)
|
140
|
+
chosen = if schema && ::Brick.db_schemas&.key?(schema)
|
130
141
|
ActiveRecord::Base.execute_sql("SET SEARCH_PATH = ?;", schema)
|
131
142
|
schema
|
132
143
|
elsif ActiveRecord::Base.connection.adapter_name == 'PostgreSQL'
|
@@ -135,6 +146,7 @@ module Brick
|
|
135
146
|
# ::Brick.apartment_multitenant && tbl_parts.first == Apartment.default_schema
|
136
147
|
(orig_schema - ['pg_catalog']).first
|
137
148
|
end
|
149
|
+
chosen == ::Brick.default_schema ? nil : chosen
|
138
150
|
end
|
139
151
|
|
140
152
|
# All tables and views (what Postgres calls "relations" including column and foreign key info)
|
@@ -207,7 +219,7 @@ module Brick
|
|
207
219
|
skip_hms[through] = nil if hms[through] && model.is_brick?
|
208
220
|
# End up with a hash of HMT names pointing to join-table associations
|
209
221
|
model._br_associatives[hmt.first] = hms[through] # || hms["#{(opt = hmt.last.options)[:through].to_s.singularize}_#{opt[:source].to_s.pluralize}".to_sym]
|
210
|
-
elsif hmt.last.inverse_of.nil?
|
222
|
+
elsif hmt.last.inverse_of.nil? && ActiveRecord.version >= ::Gem::Version.new('4.2')
|
211
223
|
puts "SKIPPING #{hmt.last.name.inspect}"
|
212
224
|
# %%% If we don't do this then below associative.name will find that associative is nil
|
213
225
|
skip_hms[hmt.last.name] = nil
|
@@ -226,6 +238,11 @@ module Brick
|
|
226
238
|
true
|
227
239
|
end
|
228
240
|
|
241
|
+
# @api public
|
242
|
+
def mode=(setting)
|
243
|
+
Brick.config.mode = setting
|
244
|
+
end
|
245
|
+
|
229
246
|
# Any path prefixing to apply to all auto-generated Brick routes
|
230
247
|
# @api public
|
231
248
|
def path_prefix=(path)
|
@@ -433,7 +450,7 @@ module Brick
|
|
433
450
|
# This is attempted early if a brick initialiser file is found, and then again as a failsafe at the end of our engine's initialisation
|
434
451
|
# %%% Maybe look for differences the second time 'round and just add new stuff instead of entirely deferring
|
435
452
|
def load_additional_references
|
436
|
-
return if @_additional_references_loaded
|
453
|
+
return if @_additional_references_loaded || ::Brick.config.mode != :on
|
437
454
|
|
438
455
|
relations = ::Brick.relations
|
439
456
|
if (ars = ::Brick.config.additional_references) || ::Brick.config.polymorphics
|
@@ -524,7 +541,11 @@ In config/initializers/brick.rb appropriate entries would look something like:
|
|
524
541
|
::Brick.is_eager_loading = true
|
525
542
|
if ::ActiveSupport.version < ::Gem::Version.new('6') ||
|
526
543
|
::Rails.configuration.instance_variable_get(:@autoloader) == :classic
|
527
|
-
::
|
544
|
+
if ::ActiveSupport.version < ::Gem::Version.new('4')
|
545
|
+
::Rails.application.eager_load!
|
546
|
+
else
|
547
|
+
::Rails.configuration.eager_load_namespaces.select { |ns| ns < ::Rails::Application }.each(&:eager_load!)
|
548
|
+
end
|
528
549
|
else
|
529
550
|
Zeitwerk::Loader.eager_load_all
|
530
551
|
end
|
@@ -546,7 +567,8 @@ In config/initializers/brick.rb appropriate entries would look something like:
|
|
546
567
|
|
547
568
|
module RouteSet
|
548
569
|
def finalize!
|
549
|
-
|
570
|
+
# %%% Was: ::Rails.application.routes.named_routes.route_defined?(:brick_status_path)
|
571
|
+
unless ::Rails.application.routes.named_routes.names.include?(:brick_status)
|
550
572
|
path_prefix = ::Brick.config.path_prefix
|
551
573
|
existing_controllers = routes.each_with_object({}) do |r, s|
|
552
574
|
c = r.defaults[:controller]
|
@@ -821,13 +843,21 @@ ActiveSupport.on_load(:active_record) do
|
|
821
843
|
end
|
822
844
|
end
|
823
845
|
|
824
|
-
# This only gets added for ActiveRecord < 3.2
|
825
846
|
module Reflection
|
847
|
+
# This only gets added for ActiveRecord < 3.2
|
826
848
|
unless AssociationReflection.instance_methods.include?(:foreign_key)
|
827
849
|
class AssociationReflection < MacroReflection
|
828
850
|
alias foreign_key association_foreign_key
|
829
851
|
end
|
830
852
|
end
|
853
|
+
# And this for ActiveRecord < 4.0
|
854
|
+
unless AssociationReflection.instance_methods.include?(:polymorphic?)
|
855
|
+
class AssociationReflection < MacroReflection
|
856
|
+
def polymorphic?
|
857
|
+
options[:polymorphic]
|
858
|
+
end
|
859
|
+
end
|
860
|
+
end
|
831
861
|
end
|
832
862
|
|
833
863
|
# ActiveRecord 3.1 and 3.2 didn't try to bring in &block for the .extending() convenience thing
|
@@ -1006,6 +1036,7 @@ ActiveSupport.on_load(:active_record) do
|
|
1006
1036
|
delegate :left_outer_joins, to: :all
|
1007
1037
|
end
|
1008
1038
|
class Relation
|
1039
|
+
alias :model :klass unless respond_to?(:model) # To support AR < 4.2
|
1009
1040
|
unless MULTI_VALUE_METHODS.include?(:left_outer_joins)
|
1010
1041
|
_multi_value_methods = MULTI_VALUE_METHODS + [:left_outer_joins]
|
1011
1042
|
send(:remove_const, :MULTI_VALUE_METHODS)
|
@@ -136,10 +136,16 @@ module Brick
|
|
136
136
|
|
137
137
|
create_file(filename, "# frozen_string_literal: true
|
138
138
|
|
139
|
-
#
|
140
|
-
#
|
139
|
+
# Settings for the Brick gem
|
140
|
+
# (By default this auto-creates models, controllers, views, and routes on-the-fly.)
|
141
141
|
|
142
142
|
if Object.const_defined?('Brick')
|
143
|
+
# Mode -- generally :on or :off, or only in :development. Also available is :diag_env which enables only
|
144
|
+
# when the environment variable BRICK is set.
|
145
|
+
Brick.mode = :development
|
146
|
+
# Can be further overridden by placing this line in development.rb / test.rb / production.rb:
|
147
|
+
# # Brick.mode = :on # (or :off to entirely disable)
|
148
|
+
|
143
149
|
# # Custom path prefix to apply to all auto-generated Brick routes. Also causes auto-generated controllers
|
144
150
|
# # to be created inside a module with the same name.
|
145
151
|
# ::Brick.path_prefix = 'admin'
|
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.86
|
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-10-
|
11
|
+
date: 2022-10-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '3.
|
19
|
+
version: '3.0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '3.
|
26
|
+
version: '3.0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: fancy_gets
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|