brick 1.0.88 → 1.0.90
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 +4 -4
- data/lib/brick/extensions.rb +29 -10
- data/lib/brick/frameworks/rails/engine.rb +38 -8
- data/lib/brick/version_number.rb +1 -1
- data/lib/brick.rb +25 -12
- 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: eca72d418715811a100a44a45b3cd054ca511ed280f1d1a6f344ddaa972c220c
|
4
|
+
data.tar.gz: d712ebb5dedf75da99d8d8720f4b89e29ea2e96b498b4a59540811f5e087231c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1b3d3941f4905b7a3ce1489a6f018d958331bd4c2970a5ba5034eb0fb81683febdc8a93562be5a1505afe6d6479fb1ed068a0f21d6ea80f24460e9e9267b8ea3
|
7
|
+
data.tar.gz: c3f61b68cd2ca5790f93b82010909f65913ccecb46df24786c83db362241092824db66833b72f03708560f23b7e87f64f12b180d8e4fb9ababba32bdb9b3f9df
|
data/lib/brick/extensions.rb
CHANGED
@@ -127,13 +127,14 @@ module ActiveRecord
|
|
127
127
|
if bracket_name
|
128
128
|
if ch == ']' # Time to process a bracketed thing?
|
129
129
|
parts = bracket_name.split('.')
|
130
|
-
first_parts = parts[0..-2].
|
131
|
-
klass = (orig_class = klass).reflect_on_association(part_sym = part.to_sym)&.klass
|
132
|
-
|
133
|
-
|
130
|
+
first_parts = parts[0..-2].each_with_object([]) do |part, s|
|
131
|
+
unless (klass = (orig_class = klass).reflect_on_association(part_sym = part.to_sym)&.klass)
|
132
|
+
puts "Couldn't reference #{orig_class.name}##{part} that's part of the DSL \"#{dsl}\"."
|
133
|
+
break
|
134
|
+
end
|
135
|
+
s << part_sym
|
134
136
|
end
|
135
|
-
parts = prefix + first_parts + [parts[-1]]
|
136
|
-
if parts.length > 1
|
137
|
+
if (parts = prefix + first_parts + [parts[-1]]).length > 1 && klass
|
137
138
|
unless is_polymorphic
|
138
139
|
s = build_array
|
139
140
|
parts[0..-3].each { |v| s = s[v.to_sym] }
|
@@ -141,7 +142,7 @@ module ActiveRecord
|
|
141
142
|
end
|
142
143
|
translations[parts[0..-2].join('.')] = klass
|
143
144
|
end
|
144
|
-
if klass
|
145
|
+
if klass&.column_names.exclude?(parts.last) &&
|
145
146
|
(klass = (orig_class = klass).reflect_on_association(possible_dsl = parts.pop.to_sym)&.klass)
|
146
147
|
if prefix.empty? # Custom columns start with an empty prefix
|
147
148
|
prefix << parts.shift until parts.empty?
|
@@ -382,6 +383,23 @@ module ActiveRecord
|
|
382
383
|
end
|
383
384
|
end
|
384
385
|
|
386
|
+
module AttributeMethods
|
387
|
+
module ClassMethods
|
388
|
+
alias _brick_dangerous_attribute_method? dangerous_attribute_method?
|
389
|
+
# Bypass the error "ActiveRecord::DangerousAttributeError" if this object comes from a view.
|
390
|
+
# (Allows for column names such as 'attribute', 'delete', and 'update' to still work.)
|
391
|
+
def dangerous_attribute_method?(name)
|
392
|
+
if (is_dangerous = _brick_dangerous_attribute_method?(name)) && is_view?
|
393
|
+
if column_names.include?(name.to_s)
|
394
|
+
puts "WARNING: Column \"#{name}\" in view #{table_name} conflicts with a reserved ActiveRecord method name."
|
395
|
+
end
|
396
|
+
return false
|
397
|
+
end
|
398
|
+
is_dangerous
|
399
|
+
end
|
400
|
+
end
|
401
|
+
end
|
402
|
+
|
385
403
|
class Relation
|
386
404
|
attr_reader :_brick_chains, :_arel_applied_aliases
|
387
405
|
|
@@ -1058,7 +1076,7 @@ Module.class_exec do
|
|
1058
1076
|
# elsif base_module != Object
|
1059
1077
|
# module_parent.const_missing(*args)
|
1060
1078
|
elsif Rails.respond_to?(:autoloaders) && # After finding nothing else, if Zeitwerk is enabled ...
|
1061
|
-
|
1079
|
+
(Rails::Autoloaders.respond_to?(:zeitwerk_enabled?) ? Rails::Autoloaders.zeitwerk_enabled? : true)
|
1062
1080
|
self._brick_const_missing(*args) # ... rely solely on Zeitwerk.
|
1063
1081
|
else # Classic mode
|
1064
1082
|
unless (found = base_module._brick_const_missing(*args))
|
@@ -1268,7 +1286,7 @@ class Object
|
|
1268
1286
|
# hm.first[:inverse][:assoc_name].to_sym
|
1269
1287
|
options[:source] = hm.last.to_sym
|
1270
1288
|
else
|
1271
|
-
through = hm.first[:alternate_name]
|
1289
|
+
through = hm.first.fetch(:alternate_chosen_name, hm.first[:alternate_name])
|
1272
1290
|
end
|
1273
1291
|
singular_assoc_name = hm.first[:inverse][:assoc_name].singularize
|
1274
1292
|
"#{singular_assoc_name}_#{hmt_fk}"
|
@@ -1689,12 +1707,13 @@ class Object
|
|
1689
1707
|
hm_assoc[:alternate_name] != (source || name.underscore)
|
1690
1708
|
plural = "#{hm_assoc[:assoc_name]}_#{ActiveSupport::Inflector.pluralize(hm_assoc[:alternate_name])}"
|
1691
1709
|
new_alt_name = (hm_assoc[:alternate_name] == name.underscore) ? "#{hm_assoc[:assoc_name].singularize}_#{plural}" : plural
|
1710
|
+
# %%% In rare cases might even need to add a number at the end for uniqueness
|
1692
1711
|
# uniq = 1
|
1693
1712
|
# while same_name = relation[:fks].find { |x| x.last[:assoc_name] == hm_assoc[:assoc_name] && x.last != hm_assoc }
|
1694
1713
|
# hm_assoc[:assoc_name] = "#{hm_assoc_name}_#{uniq += 1}"
|
1695
1714
|
# end
|
1696
1715
|
# puts new_alt_name
|
1697
|
-
|
1716
|
+
hm_assoc[:alternate_chosen_name] = new_alt_name
|
1698
1717
|
[new_alt_name, true]
|
1699
1718
|
else
|
1700
1719
|
assoc_name = ::Brick.namify(hm_assoc[:inverse_table]).pluralize
|
@@ -818,7 +818,16 @@ erDiagram
|
|
818
818
|
end # DutyFree data export and import
|
819
819
|
# %%% Instead of our current "for Janet Leverling (Employee)" kind of link we previously had this code that did a "where x = 123" thing:
|
820
820
|
# (where <%= @_brick_params.each_with_object([]) { |v, s| s << \"#\{v.first\} = #\{v.last.inspect\}\" }.join(', ') %>)
|
821
|
-
+"
|
821
|
+
+"<html>
|
822
|
+
<head>
|
823
|
+
#{css}
|
824
|
+
<title>#{model_name} <%
|
825
|
+
if (description = (relation = Brick.relations[#{model_name}.table_name])&.fetch(:description, nil)).present?
|
826
|
+
%> - <%= description
|
827
|
+
%><% end
|
828
|
+
%></title>
|
829
|
+
</head>
|
830
|
+
<body>
|
822
831
|
<p style=\"color: green\"><%= notice %></p>#{"
|
823
832
|
<select id=\"schema\">#{schema_options}</select>" if ::Brick.config.schema_behavior[:multitenant] && ::Brick.db_schemas.length > 1}
|
824
833
|
<select id=\"tbl\">#{table_options}</select>
|
@@ -826,7 +835,7 @@ erDiagram
|
|
826
835
|
<td><h1>#{model_name}</h1></td>
|
827
836
|
<td id=\"imgErd\" title=\"Show ERD\"></td>
|
828
837
|
</tr></table>#{template_link}<%
|
829
|
-
if
|
838
|
+
if description.present? %><%=
|
830
839
|
description %><br><%
|
831
840
|
end
|
832
841
|
# FILTER PARAMETERS
|
@@ -988,7 +997,10 @@ erDiagram
|
|
988
997
|
</table>
|
989
998
|
|
990
999
|
#{"<hr><%= link_to \"New #{obj_name}\", new_#{path_obj_name}_path %>" unless @_brick_model.is_view?}
|
991
|
-
#{script}
|
1000
|
+
#{script}
|
1001
|
+
</body>
|
1002
|
+
</html>
|
1003
|
+
"
|
992
1004
|
|
993
1005
|
when 'status'
|
994
1006
|
if is_status
|
@@ -1061,7 +1073,14 @@ erDiagram
|
|
1061
1073
|
end
|
1062
1074
|
|
1063
1075
|
when 'show', 'new', 'update'
|
1064
|
-
+"
|
1076
|
+
+"<html>
|
1077
|
+
<head>
|
1078
|
+
#{css}
|
1079
|
+
<title><%=
|
1080
|
+
page_title = (\"#{model_name}: #\{(obj = @#{obj_name})&.brick_descrip || controller_name}\")
|
1081
|
+
%></title>
|
1082
|
+
</head>
|
1083
|
+
<body>
|
1065
1084
|
|
1066
1085
|
<svg id=\"revertTemplate\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"
|
1067
1086
|
width=\"32px\" height=\"32px\" viewBox=\"0 0 512 512\" xml:space=\"preserve\">
|
@@ -1072,7 +1091,7 @@ erDiagram
|
|
1072
1091
|
<p style=\"color: green\"><%= notice %></p>#{"
|
1073
1092
|
<select id=\"schema\">#{schema_options}</select>" if ::Brick.config.schema_behavior[:multitenant] && ::Brick.db_schemas.length > 1}
|
1074
1093
|
<select id=\"tbl\">#{table_options}</select>
|
1075
|
-
<h1
|
1094
|
+
<h1><%= page_title %></h1><%
|
1076
1095
|
if (description = (relation = Brick.relations[#{model_name}.table_name])&.fetch(:description, nil)) %><%=
|
1077
1096
|
description %><br><%
|
1078
1097
|
end
|
@@ -1201,7 +1220,8 @@ end
|
|
1201
1220
|
<% end %>
|
1202
1221
|
|
1203
1222
|
#{unless args.first == 'new'
|
1204
|
-
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?' } }"
|
1223
|
+
# 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?' } }"
|
1224
|
+
confirm_are_you_sure = "data: { confirm: 'Delete #{model_name} -- Are you sure?' }"
|
1205
1225
|
hms_headers.each_with_object(+'') do |hm, s|
|
1206
1226
|
# %%% Would be able to remove this when multiple foreign keys to same destination becomes bulletproof
|
1207
1227
|
next if hm.first.options[:through] && !hm.first.through_reflection
|
@@ -1212,7 +1232,14 @@ end
|
|
1212
1232
|
s << "<table id=\"#{hm_name}\" class=\"shadow\">
|
1213
1233
|
<tr><th>#{hm[3]}</th></tr>
|
1214
1234
|
<% collection = @#{obj_name}.#{hm_name}
|
1215
|
-
collection =
|
1235
|
+
collection = case collection
|
1236
|
+
when ActiveRecord::Associations::CollectionProxy
|
1237
|
+
collection.order(#{pk.inspect})
|
1238
|
+
when ActiveRecord::Base # Object from a has_one
|
1239
|
+
[collection]
|
1240
|
+
else # We get an array back when AR < 4.2
|
1241
|
+
collection.to_a.compact
|
1242
|
+
end
|
1216
1243
|
if collection.empty? %>
|
1217
1244
|
<tr><td>(none)</td></tr>
|
1218
1245
|
<% else %>
|
@@ -1228,7 +1255,10 @@ end
|
|
1228
1255
|
"<%= 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} }) %>"
|
1229
1256
|
end}
|
1230
1257
|
<% end %>
|
1231
|
-
#{script}
|
1258
|
+
#{script}
|
1259
|
+
</body>
|
1260
|
+
</html>
|
1261
|
+
"
|
1232
1262
|
|
1233
1263
|
end
|
1234
1264
|
inline << "
|
data/lib/brick/version_number.rb
CHANGED
data/lib/brick.rb
CHANGED
@@ -186,15 +186,15 @@ module Brick
|
|
186
186
|
|
187
187
|
def get_bts_and_hms(model)
|
188
188
|
bts, hms = model.reflect_on_all_associations.each_with_object([{}, {}]) do |a, s|
|
189
|
-
next
|
189
|
+
next unless a.polymorphic? || (!a.belongs_to? && (through = a.options[:through])) ||
|
190
|
+
(a.klass && ::Brick.config.exclude_tables.exclude?(a.klass.table_name))
|
190
191
|
|
191
|
-
|
192
|
-
when :belongs_to
|
192
|
+
if a.belongs_to?
|
193
193
|
if a.polymorphic?
|
194
194
|
rel_poly_bt = relations[model.table_name][:fks].find { |_k, fk| fk[:assoc_name] == a.name.to_s }
|
195
195
|
if (primary_tables = rel_poly_bt&.last&.fetch(:inverse_table, [])).is_a?(Array)
|
196
196
|
models = primary_tables&.map { |table| table.singularize.camelize.constantize }
|
197
|
-
s.first[a.foreign_key] = [a.name, models, true]
|
197
|
+
s.first[a.foreign_key.to_s] = [a.name, models, true]
|
198
198
|
else
|
199
199
|
# This will come up when using Devise invitable when invited_by_class_name is not
|
200
200
|
# specified because in that circumstance it adds a polymorphic :invited_by association,
|
@@ -203,10 +203,26 @@ module Brick
|
|
203
203
|
puts " belongs_to :#{a.name}, polymorphic: true"
|
204
204
|
end
|
205
205
|
else
|
206
|
-
s.first[a.foreign_key] = [a.name, a.klass]
|
206
|
+
s.first[a.foreign_key.to_s] = [a.name, a.klass]
|
207
|
+
end
|
208
|
+
else # This gets has_many as well as has_one and has_many :through
|
209
|
+
if through
|
210
|
+
is_invalid_source = nil
|
211
|
+
begin
|
212
|
+
if a.through_reflection&.belongs_to?
|
213
|
+
puts "WARNING: HMT relationship :#{a.name} in model #{model.name} tries to go through belongs_to association :#{through}. This is not possible."
|
214
|
+
next
|
215
|
+
elsif !a.source_reflection # Had considered: a.active_record.reflect_on_association(a.source_reflection_name).nil?
|
216
|
+
is_invalid_source = true
|
217
|
+
end
|
218
|
+
rescue
|
219
|
+
is_invalid_source = true
|
220
|
+
end
|
221
|
+
if is_invalid_source
|
222
|
+
puts "WARNING: HMT relationship :#{a.name} in model #{model.name} has invalid source :#{a.source_reflection_name}."
|
223
|
+
next
|
224
|
+
end
|
207
225
|
end
|
208
|
-
when :has_many, :has_one # This gets has_many as well as has_many :through
|
209
|
-
# %%% weed out ones that don't have an available model to reference
|
210
226
|
s.last[a.name] = a
|
211
227
|
end
|
212
228
|
end
|
@@ -216,13 +232,10 @@ module Brick
|
|
216
232
|
hms.each do |hmt|
|
217
233
|
if (through = hmt.last.options[:through])
|
218
234
|
# ::Brick.relations[hmt.last.through_reflection.table_name]
|
219
|
-
skip_hms[through] = nil if hms[through] && model.is_brick?
|
235
|
+
skip_hms[through] = nil if hms[through] && model.is_brick? &&
|
236
|
+
hmt.last.klass != hmt.last.active_record # Don't pull HMs for HMTs that point back to the same table
|
220
237
|
# End up with a hash of HMT names pointing to join-table associations
|
221
238
|
model._br_associatives[hmt.first] = hms[through] # || hms["#{(opt = hmt.last.options)[:through].to_s.singularize}_#{opt[:source].to_s.pluralize}".to_sym]
|
222
|
-
elsif hmt.last.inverse_of.nil? && ActiveRecord.version >= ::Gem::Version.new('4.2')
|
223
|
-
puts "SKIPPING #{hmt.last.name.inspect}"
|
224
|
-
# %%% If we don't do this then below associative.name will find that associative is nil
|
225
|
-
skip_hms[hmt.last.name] = nil
|
226
239
|
end
|
227
240
|
end
|
228
241
|
skip_hms.each { |k, _v| hms.delete(k) }
|
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.90
|
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-11-
|
11
|
+
date: 2022-11-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|