brick 1.0.16 → 1.0.17
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/config.rb +4 -4
- data/lib/brick/extensions.rb +6 -2
- data/lib/brick/frameworks/rails/engine.rb +68 -28
- data/lib/brick/version_number.rb +1 -1
- data/lib/brick.rb +14 -2
- data/lib/generators/brick/install_generator.rb +1 -1
- 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: 7f1a45a5262526e69cf49f16773049eb348e3971bddf09ecf05927002a265019
|
4
|
+
data.tar.gz: e9566a423a19ab55d44522b44e8b4abfcc39e92335b6093fe782c6344644bbbe
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cb89dff96dccc7051bc854fe523b03f818255d81e4f2e2a65eb9808115e719b8bad98e38114f15ee79b32b1f035c95c364a74392948cd2e99f4030e6988e0217
|
7
|
+
data.tar.gz: cd5507fde2f1f23481696ab051d14f89e5e7e7d3fc2be97af947ff287313b7ada8ca7b4e3f9e0e54dc2ab7f14e7f39a3c18f78cf7fc995c58b3d60cf68487973
|
data/lib/brick/config.rb
CHANGED
@@ -66,12 +66,12 @@ module Brick
|
|
66
66
|
end
|
67
67
|
|
68
68
|
# Skip creating a has_many association for these
|
69
|
-
def
|
70
|
-
@mutex.synchronize { @
|
69
|
+
def exclude_hms
|
70
|
+
@mutex.synchronize { @exclude_hms }
|
71
71
|
end
|
72
72
|
|
73
|
-
def
|
74
|
-
@mutex.synchronize { @
|
73
|
+
def exclude_hms=(skips)
|
74
|
+
@mutex.synchronize { @exclude_hms = skips }
|
75
75
|
end
|
76
76
|
|
77
77
|
# Associations to treat as a has_one
|
data/lib/brick/extensions.rb
CHANGED
@@ -629,7 +629,11 @@ module ActiveRecord::ConnectionHandling
|
|
629
629
|
puts "\nClasses that can be built from views:"
|
630
630
|
views.keys.each { |k| puts ActiveSupport::Inflector.singularize(k).camelize }
|
631
631
|
end
|
632
|
-
#
|
632
|
+
# Try to load the initializer pretty danged early
|
633
|
+
if File.exist?(brick_initialiser = Rails.root.join('config/initializers/brick.rb'))
|
634
|
+
load brick_initialiser
|
635
|
+
::Brick.load_additional_references
|
636
|
+
end
|
633
637
|
|
634
638
|
# relations.keys.each { |k| ActiveSupport::Inflector.singularize(k).camelize.constantize }
|
635
639
|
# Layout table describes permissioned hierarchy throughout
|
@@ -708,7 +712,7 @@ module Brick
|
|
708
712
|
# assoc_bt[:inverse_of] = primary_class.reflect_on_all_associations.find { |a| a.foreign_key == bt[1] }
|
709
713
|
end
|
710
714
|
|
711
|
-
unless is_class || ::Brick.config.
|
715
|
+
unless is_class || ::Brick.config.exclude_hms&.any? { |exclusion| fk[0] == exclusion[0] && fk[1] == exclusion[1] && primary_table == exclusion[2] }
|
712
716
|
cnstr_name = "hm_#{cnstr_name}"
|
713
717
|
if (assoc_hm = hms.fetch(cnstr_name, nil))
|
714
718
|
assoc_hm[:fk] = assoc_hm[:fk].is_a?(String) ? [assoc_hm[:fk], fk[1]] : assoc_hm[:fk].concat(fk[1])
|
@@ -32,7 +32,7 @@ module Brick
|
|
32
32
|
::Brick.additional_references = app.config.brick.fetch(:additional_references, nil)
|
33
33
|
|
34
34
|
# Skip creating a has_many association for these
|
35
|
-
::Brick.
|
35
|
+
::Brick.exclude_hms = app.config.brick.fetch(:exclude_hms, nil)
|
36
36
|
|
37
37
|
# Has one relationships
|
38
38
|
::Brick.has_ones = app.config.brick.fetch(:has_ones, nil)
|
@@ -76,33 +76,34 @@ module Brick
|
|
76
76
|
bts, hms = ::Brick.get_bts_and_hms(@_brick_model)
|
77
77
|
# Mark has_manys that go to an associative ("join") table so that they are skipped in the UI,
|
78
78
|
# as well as any possible polymorphic associations
|
79
|
-
|
79
|
+
exclude_hms = {}
|
80
80
|
associatives = hms.each_with_object({}) do |hmt, s|
|
81
81
|
if (through = hmt.last.options[:through])
|
82
|
-
|
82
|
+
exclude_hms[through] = nil
|
83
83
|
s[hmt.first] = hms[through] # End up with a hash of HMT names pointing to join-table associations
|
84
84
|
elsif hmt.last.inverse_of.nil?
|
85
85
|
puts "SKIPPING #{hmt.last.name.inspect}"
|
86
86
|
# %%% If we don't do this then below associative.name will find that associative is nil
|
87
|
-
|
87
|
+
exclude_hms[hmt.last.name] = nil
|
88
88
|
end
|
89
89
|
end
|
90
90
|
|
91
91
|
schema_options = ::Brick.db_schemas.each_with_object(+'') { |v, s| s << "<option value=\"#{v}\">#{v}</option>" }.html_safe
|
92
|
+
table_options = ::Brick.relations.keys.each_with_object(+'') { |v, s| s << "<option value=\"#{v}\">#{v}</option>" }.html_safe
|
92
93
|
hms_columns = +'' # Used for 'index'
|
93
94
|
hms_headers = hms.each_with_object([]) do |hm, s|
|
94
|
-
next if
|
95
|
+
next if exclude_hms.key?((hm_assoc = hm.last).name)
|
95
96
|
|
96
97
|
if args.first == 'index'
|
97
|
-
hm_fk_name = if
|
98
|
-
associative = associatives[
|
98
|
+
hm_fk_name = if hm_assoc.options[:through]
|
99
|
+
associative = associatives[hm_assoc.name]
|
99
100
|
"'#{associative.name}.#{associative.foreign_key}'"
|
100
101
|
else
|
101
|
-
|
102
|
+
hm_assoc.foreign_key
|
102
103
|
end
|
103
|
-
hms_columns << if
|
104
|
+
hms_columns << if hm_assoc.macro == :has_many
|
104
105
|
"<td>
|
105
|
-
<%= link_to \"#\{#{obj_name}.#{hm.first}.count\} #{hm.first}\", #{
|
106
|
+
<%= link_to \"#\{#{obj_name}.#{hm.first}.count\} #{hm.first}\", #{hm_assoc.klass.name.underscore.pluralize}_path({ #{hm_fk_name}: #{obj_name}.#{pk} }) unless #{obj_name}.#{hm.first}.count.zero? %>
|
106
107
|
</td>\n"
|
107
108
|
else # has_one
|
108
109
|
"<td>
|
@@ -110,7 +111,7 @@ module Brick
|
|
110
111
|
</td>\n"
|
111
112
|
end
|
112
113
|
end
|
113
|
-
s << [
|
114
|
+
s << [hm_assoc, "H#{hm_assoc.macro == :has_one ? 'O' : 'M'}#{'T' if hm_assoc.options[:through]} #{hm.first}"]
|
114
115
|
end
|
115
116
|
|
116
117
|
css = "<style>
|
@@ -155,10 +156,20 @@ table tbody tr.active-row {
|
|
155
156
|
}
|
156
157
|
|
157
158
|
a.show-arrow {
|
159
|
+
font-size: 1.5em;
|
160
|
+
text-decoration: none;
|
161
|
+
}
|
162
|
+
a.big-arrow {
|
158
163
|
font-size: 2.5em;
|
159
164
|
text-decoration: none;
|
160
165
|
}
|
161
|
-
</style>
|
166
|
+
</style>
|
167
|
+
<% def is_bcrypt?(val)
|
168
|
+
val.is_a?(String) && val.length == 60 && val.start_with?('$2a$')
|
169
|
+
end
|
170
|
+
def hide_bcrypt(val)
|
171
|
+
is_bcrypt?(val) ? '(hidden)' : val
|
172
|
+
end %>"
|
162
173
|
|
163
174
|
script = "<script>
|
164
175
|
var schemaSelect = document.getElementById(\"schema\");
|
@@ -173,8 +184,28 @@ if (schemaSelect) {
|
|
173
184
|
location.href = changeout(location.href, \"_brick_schema\", this.value);
|
174
185
|
});
|
175
186
|
}
|
187
|
+
|
188
|
+
var tblSelect = document.getElementById(\"tbl\");
|
189
|
+
if (tblSelect) {
|
190
|
+
tblSelect.value = changeout(location.href);
|
191
|
+
tblSelect.addEventListener(\"change\", function () {
|
192
|
+
var lhr = changeout(location.href, null, this.value);
|
193
|
+
if (brickSchema)
|
194
|
+
lhr = changeout(lhr, \"_brick_schema\", schemaSelect.value);
|
195
|
+
location.href = lhr;
|
196
|
+
});
|
197
|
+
}
|
198
|
+
|
176
199
|
function changeout(href, param, value) {
|
177
200
|
var hrefParts = href.split(\"?\");
|
201
|
+
if (param === undefined || param === null) {
|
202
|
+
hrefParts = hrefParts[0].split(\"://\");
|
203
|
+
var pathParts = hrefParts[hrefParts.length - 1].split(\"/\");
|
204
|
+
if (value === undefined)
|
205
|
+
return pathParts[1];
|
206
|
+
else
|
207
|
+
return hrefParts[0] + \"://\" + pathParts[0] + \"/\" + value;
|
208
|
+
}
|
178
209
|
var params = hrefParts.length > 1 ? hrefParts[1].split(\"&\") : [];
|
179
210
|
params = params.reduce(function (s, v) { var parts = v.split(\"=\"); s[parts[0]] = parts[1]; return s; }, {});
|
180
211
|
if (value === undefined) return params[param];
|
@@ -188,6 +219,7 @@ function changeout(href, param, value) {
|
|
188
219
|
"#{css}
|
189
220
|
<p style=\"color: green\"><%= notice %></p>#{"
|
190
221
|
<select id=\"schema\">#{schema_options}</select>" if ::Brick.db_schemas.length > 1}
|
222
|
+
<select id=\"tbl\">#{table_options}</select>
|
191
223
|
<h1>#{model_name.pluralize}</h1>
|
192
224
|
<% if @_brick_params&.present? %><h3>where <%= @_brick_params.each_with_object([]) { |v, s| s << \"#\{v.first\} = #\{v.last.inspect\}\" }.join(', ') %></h3><% end %>
|
193
225
|
<table id=\"#{table_name}\">
|
@@ -209,7 +241,7 @@ function changeout(href, param, value) {
|
|
209
241
|
<tbody>
|
210
242
|
<% @#{table_name}.each do |#{obj_name}| %>
|
211
243
|
<tr>#{"
|
212
|
-
<td><%= link_to '⇛', #{obj_name}_path(#{obj_name}.#{pk}), { class: '
|
244
|
+
<td><%= link_to '⇛', #{obj_name}_path(#{obj_name}.#{pk}), { class: 'big-arrow' } %></td>" if pk }
|
213
245
|
<% #{obj_name}.attributes.each do |k, val| %>
|
214
246
|
<% next if k == '#{pk}' || ::Brick.config.metadata_columns.include?(k) %>
|
215
247
|
<td>
|
@@ -218,9 +250,9 @@ function changeout(href, param, value) {
|
|
218
250
|
# send(\"#\{bt_obj_class = bt[1].name.underscore\}_path\".to_sym, bt_obj.send(bt[1].primary_key.to_sym))
|
219
251
|
# Otherwise we get stuff like:
|
220
252
|
# ActionView::Template::Error (undefined method `vehicle_path' for #<ActionView::Base:0x0000000033a888>) %>
|
221
|
-
<%= bt_obj = bt[1].find_by(bt
|
253
|
+
<%= bt_obj = bt[1].find_by(bt[2] => val); link_to(bt_obj.brick_descrip, send(\"#\{bt_obj_class = bt[1].name.underscore\}_path\".to_sym, bt_obj.send(bt[1].primary_key.to_sym))) if bt_obj %>
|
222
254
|
<% else %>
|
223
|
-
<%= val %>
|
255
|
+
<%= hide_bcrypt(val) %>
|
224
256
|
<% end %>
|
225
257
|
</td>
|
226
258
|
<% end %>
|
@@ -237,40 +269,51 @@ function changeout(href, param, value) {
|
|
237
269
|
"#{css}
|
238
270
|
<p style=\"color: green\"><%= notice %></p>#{"
|
239
271
|
<select id=\"schema\">#{schema_options}</select>" if ::Brick.db_schemas.length > 1}
|
272
|
+
<select id=\"tbl\">#{table_options}</select>
|
240
273
|
<h1>#{model_name}: <%= (obj = @#{obj_name}.first).brick_descrip %></h1>
|
241
274
|
<%= link_to '(See all #{obj_name.pluralize})', #{table_name}_path %>
|
275
|
+
<%= form_for obj do |f| %>
|
242
276
|
<table>
|
243
277
|
<% bts = { #{bts.each_with_object([]) { |v, s| s << "#{v.first.inspect} => [#{v.last.first.inspect}, #{v.last[1].name}, #{v.last[1].primary_key.inspect}]"}.join(', ')} }
|
244
278
|
@#{obj_name}.first.attributes.each do |k, val| %>
|
245
279
|
<tr>
|
246
280
|
<% next if k == '#{pk}' || ::Brick.config.metadata_columns.include?(k) %>
|
247
281
|
<th class=\"show-field\">
|
248
|
-
<% if (bt = bts[k])
|
282
|
+
<% if (bt = bts[k])
|
283
|
+
# Add a final member in this array with descriptive options to be used in <select> drop-downs
|
284
|
+
# %%% Only do this if the user has permissions to edit this bt field
|
285
|
+
bt << bt[1].order(:#{pk}).map { |obj| [obj.brick_descrip, obj.#{pk}] } if bt.length < 4 %>
|
249
286
|
BT <%= \"#\{bt.first\}-\" unless bt[1].name.underscore == bt.first.to_s %><%= bt[1].name %>
|
250
287
|
<% else %>
|
251
288
|
<%= k %>
|
252
289
|
<% end %>
|
253
290
|
</th>
|
254
291
|
<td>
|
255
|
-
<% if (bt = bts[k]) %>
|
256
|
-
<%=
|
292
|
+
<% if (bt = bts[k]) # bt_obj.brick_descrip %>
|
293
|
+
<%= f.select k.to_sym, bt[3], {}, prompt: 'Select #{model_name}' %>
|
294
|
+
<%= bt_obj = bt[1].find_by(bt[2] => val); link_to('⇛', send(\"#\{bt_obj_class = bt[1].name.underscore\}_path\".to_sym, bt_obj.send(bt[1].primary_key.to_sym)), { class: 'show-arrow' }) if bt_obj %>
|
295
|
+
<% elsif is_bcrypt?(val) %>
|
296
|
+
<%= hide_bcrypt(val) %>
|
257
297
|
<% else %>
|
258
|
-
<%=
|
298
|
+
<%= f.text_field k.to_sym %>
|
259
299
|
<% end %>
|
260
300
|
</td>
|
261
301
|
</tr>
|
262
302
|
<% end %>
|
263
303
|
</table>
|
304
|
+
<% end %>
|
264
305
|
|
265
306
|
#{hms_headers.map do |hm|
|
266
307
|
next unless (pk = hm.first.klass.primary_key)
|
267
308
|
"<table id=\"#{hm_name = hm.first.name.to_s}\">
|
268
309
|
<tr><th>#{hm.last}</th></tr>
|
269
|
-
<%
|
310
|
+
<% collection = @#{obj_name}.first.#{hm_name}
|
311
|
+
collection = collection.is_a?(ActiveRecord::Associations::CollectionProxy) ? collection.order(#{pk.inspect}) : [collection]
|
312
|
+
if collection.empty? %>
|
270
313
|
<tr><td>(none)</td></tr>
|
271
314
|
<% else %>
|
272
|
-
<% collection.
|
273
|
-
<tr><td><%= link_to(#{hm_singular_name}.brick_descrip, #{
|
315
|
+
<% collection.uniq.each do |#{hm_singular_name = hm_name.singularize.underscore}| %>
|
316
|
+
<tr><td><%= link_to(#{hm_singular_name}.brick_descrip, #{hm.first.klass.name.underscore}_path(#{hm_singular_name}.#{pk})) %></td></tr>
|
274
317
|
<% end %>
|
275
318
|
<% end %>
|
276
319
|
</table>" end.join}
|
@@ -295,12 +338,9 @@ function changeout(href, param, value) {
|
|
295
338
|
end
|
296
339
|
end
|
297
340
|
|
298
|
-
#
|
299
|
-
|
300
|
-
|
301
|
-
::Brick._add_bt_and_hm(fk[0..2])
|
302
|
-
end
|
303
|
-
end
|
341
|
+
# Just in case it hadn't been done previously when we tried to load the brick initialiser,
|
342
|
+
# go make sure we've loaded additional references (virtual foreign keys).
|
343
|
+
::Brick.load_additional_references
|
304
344
|
|
305
345
|
# Find associative tables that can be set up for has_many :through
|
306
346
|
::Brick.relations.each do |_key, tbl|
|
data/lib/brick/version_number.rb
CHANGED
data/lib/brick.rb
CHANGED
@@ -208,12 +208,12 @@ module Brick
|
|
208
208
|
# Skip creating a has_many association for these
|
209
209
|
# (Uses the same exact three-part format as would define an additional_reference)
|
210
210
|
# @api public
|
211
|
-
def
|
211
|
+
def exclude_hms=(skips)
|
212
212
|
if skips
|
213
213
|
skips = skips.call if skips.is_a?(Proc)
|
214
214
|
skips = skips.to_a unless skips.is_a?(Array)
|
215
215
|
skips = [skips] unless skips.empty? || skips.first.is_a?(Array)
|
216
|
-
Brick.config.
|
216
|
+
Brick.config.exclude_hms = skips
|
217
217
|
end
|
218
218
|
end
|
219
219
|
|
@@ -244,6 +244,18 @@ module Brick
|
|
244
244
|
Brick.config.sti_namespace_prefixes = snp
|
245
245
|
end
|
246
246
|
|
247
|
+
# Load additional references (virtual foreign keys)
|
248
|
+
# 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
|
249
|
+
# %%% Maybe look for differences the second time 'round and just add new stuff instead of entirely deferring
|
250
|
+
def load_additional_references
|
251
|
+
return if @_additional_references_loaded
|
252
|
+
|
253
|
+
if (ars = ::Brick.config.additional_references)
|
254
|
+
ars.each { |fk| ::Brick._add_bt_and_hm(fk[0..2]) }
|
255
|
+
@_additional_references_loaded = true
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
247
259
|
|
248
260
|
# Returns Brick's `::Gem::Version`, convenient for comparisons. This is
|
249
261
|
# recommended over `::Brick::VERSION::STRING`.
|
@@ -114,7 +114,7 @@ module Brick
|
|
114
114
|
# # Skip creating a has_many association for these
|
115
115
|
# # (Uses the same exact three-part format as would define an additional_reference)
|
116
116
|
# # Say for instance that we didn't care to display the favourite colours that users have:
|
117
|
-
# Brick.
|
117
|
+
# Brick.exclude_hms = [['users', 'favourite_colour_id', 'colours']]
|
118
118
|
|
119
119
|
# # By default primary tables involved in a foreign key relationship will indicate a \"has_many\" relationship pointing
|
120
120
|
# # back to the foreign table. In order to represent a \"has_one\" association instead, an override can be provided
|
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.17
|
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-03-
|
11
|
+
date: 2022-03-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|