brick 1.0.27 → 1.0.30

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.
@@ -55,7 +55,9 @@ module Brick
55
55
  unless (is_template_exists = _brick_template_exists?(*args, **options))
56
56
  # Need to return true if we can fill in the blanks for a missing one
57
57
  # args will be something like: ["index", ["categories"]]
58
- model = args[1].map(&:camelize).join('::').singularize.constantize
58
+ args[1] = args[1].each_with_object([]) { |a, s| s.concat(a.split('/')) }
59
+ args[1][args[1].length - 1] = args[1].last.singularize # Make sure the last item, defining the class name, is singular
60
+ model = args[1].map(&:camelize).join('::').constantize
59
61
  if is_template_exists = model && (
60
62
  ['index', 'show'].include?(args.first) || # Everything has index and show
61
63
  # Only CUD stuff has create / update / destroy
@@ -71,9 +73,10 @@ module Brick
71
73
  keys = if fk_name.is_a?(Array) && pk.is_a?(Array) # Composite keys?
72
74
  fk_name.zip(pk.map { |pk_part| "#{obj_name}.#{pk_part}" })
73
75
  else
74
- [[fk_name, "#{obj_name}.#{pk}"]]
76
+ pk = pk.each_with_object([]) { |pk_part, s| s << "#{obj_name}.#{pk_part}" }
77
+ [[fk_name, pk.length == 1 ? pk.first : pk.inspect]]
75
78
  end
76
- keys << [hm_assoc.inverse_of.foreign_type, "#{hm_assoc.active_record.name}"] if hm_assoc.options.key?(:as)
79
+ keys << [hm_assoc.inverse_of.foreign_type, hm_assoc.active_record.name] if hm_assoc.options.key?(:as)
77
80
  keys.map { |x| "#{x.first}: #{x.last}"}.join(', ')
78
81
  end
79
82
 
@@ -82,9 +85,10 @@ module Brick
82
85
  return _brick_find_template(*args, **options) unless @_brick_model
83
86
 
84
87
  model_name = @_brick_model.name
85
- pk = @_brick_model.primary_key
86
- obj_name = model_name.underscore
87
- table_name = model_name.pluralize.underscore
88
+ pk = @_brick_model._brick_primary_key(::Brick.relations.fetch(model_name, nil))
89
+ obj_name = model_name.split('::').last.underscore
90
+ path_obj_name = model_name.underscore.tr('/', '_')
91
+ table_name = obj_name.pluralize
88
92
  template_link = nil
89
93
  bts, hms, associatives = ::Brick.get_bts_and_hms(@_brick_model) # This gets BT and HM and also has_many :through (HMT)
90
94
  hms_columns = [] # Used for 'index'
@@ -107,21 +111,21 @@ module Brick
107
111
  "#{obj_name}.#{attrib_name} || 0"
108
112
  end
109
113
  "<%= ct = #{set_ct}
110
- link_to \"#\{ct || 'View'\} #{assoc_name}\", #{hm_assoc.klass.name.underscore.pluralize}_path({ #{path_keys(hm_assoc, hm_fk_name, obj_name, pk)} }) unless ct&.zero? %>\n"
114
+ link_to \"#\{ct || 'View'\} #{assoc_name}\", #{hm_assoc.klass.name.underscore.tr('/', '_').pluralize}_path({ #{path_keys(hm_assoc, hm_fk_name, obj_name, pk)} }) unless ct&.zero? %>\n"
111
115
  else # has_one
112
116
  "<%= obj = #{obj_name}.#{hm.first}; link_to(obj.brick_descrip, obj) if obj %>\n"
113
117
  end
114
118
  elsif args.first == 'show'
115
- hm_stuff << "<%= link_to '#{assoc_name}', #{hm_assoc.klass.name.underscore.pluralize}_path({ #{path_keys(hm_assoc, hm_fk_name, "@#{obj_name}", pk)} }) %>\n"
119
+ hm_stuff << "<%= link_to '#{assoc_name}', #{hm_assoc.klass.name.underscore.tr('/', '_').pluralize}_path({ #{path_keys(hm_assoc, hm_fk_name, "@#{obj_name}", pk)} }) %>\n"
116
120
  end
117
121
  s << hm_stuff
118
122
  end
119
123
 
120
- schema_options = ::Brick.db_schemas.each_with_object(+'') { |v, s| s << "<option value=\"#{v}\">#{v}</option>" }.html_safe
124
+ schema_options = ::Brick.db_schemas.keys.each_with_object(+'') { |v, s| s << "<option value=\"#{v}\">#{v}</option>" }.html_safe
121
125
  # %%% If we are not auto-creating controllers (or routes) then omit by default, and if enabled anyway, such as in a development
122
126
  # environment or whatever, then get either the controllers or routes list instead
123
- table_options = (::Brick.relations.keys - ::Brick.config.exclude_tables)
124
- .each_with_object(+'') { |v, s| s << "<option value=\"#{v.underscore.pluralize}\">#{v}</option>" }.html_safe
127
+ table_options = (::Brick.relations.keys - ::Brick.config.exclude_tables).sort
128
+ .each_with_object(+'') { |v, s| s << "<option value=\"#{v.underscore.gsub('.', '/').pluralize}\">#{v}</option>" }.html_safe
125
129
  css = +"<style>
126
130
  #dropper {
127
131
  background-color: #eee;
@@ -206,7 +210,13 @@ input[type=submit] {
206
210
  val.is_a?(String) && val.length == 60 && val.start_with?('$2a$')
207
211
  end
208
212
  def hide_bcrypt(val)
209
- is_bcrypt?(val) ? '(hidden)' : val
213
+ if is_bcrypt?(val)
214
+ '(hidden)'
215
+ elsif val.is_a?(String) && val.encoding.name != 'UTF-8'
216
+ val[0..1000].force_encoding('UTF-8')
217
+ else
218
+ val
219
+ end
210
220
  end %>"
211
221
 
212
222
  if ['index', 'show', 'update'].include?(args.first)
@@ -254,7 +264,8 @@ if (schemaSelect) {
254
264
 
255
265
  var tblSelect = document.getElementById(\"tbl\");
256
266
  if (tblSelect) {
257
- tblSelect.value = changeout(location.href);
267
+ tblSelect.value = changeout(location.href)[0];
268
+ if (tblSelect.selectedIndex < 0) tblSelect.value = changeout(location.href)[1];
258
269
  tblSelect.addEventListener(\"change\", function () {
259
270
  var lhr = changeout(location.href, null, this.value);
260
271
  if (brickSchema)
@@ -269,7 +280,8 @@ function changeout(href, param, value) {
269
280
  hrefParts = hrefParts[0].split(\"://\");
270
281
  var pathParts = hrefParts[hrefParts.length - 1].split(\"/\");
271
282
  if (value === undefined)
272
- return pathParts[1];
283
+ // A couple possibilities if it's namespaced, starting with two parts in the path -- and then try just one
284
+ return [pathParts.slice(1, 3).join('/'), pathParts.slice(1, 2)];
273
285
  else
274
286
  return hrefParts[0] + \"://\" + pathParts[0] + \"/\" + value;
275
287
  }
@@ -283,7 +295,7 @@ function changeout(href, param, value) {
283
295
  inline = case args.first
284
296
  when 'index'
285
297
  obj_pk = if pk&.is_a?(Array) # Composite primary key?
286
- "[#{pk.map { |pk_part| "#{obj_name}.#{pk_part}" }.join(', ')}]"
298
+ "[#{pk.map { |pk_part| "#{obj_name}.#{pk_part}" }.join(', ')}]" unless pk.empty?
287
299
  elsif pk
288
300
  "#{obj_name}.#{pk}"
289
301
  end
@@ -306,7 +318,7 @@ function changeout(href, param, value) {
306
318
  btnImport.style.display = droppedTSV.length > 0 ? \"block\" : \"none\";
307
319
  });
308
320
  btnImport.addEventListener(\"click\", function () {
309
- fetch(changeout(<%= #{obj_name}_path(-1, format: :csv).inspect.html_safe %>, \"_brick_schema\", brickSchema), {
321
+ fetch(changeout(<%= #{path_obj_name}_path(-1, format: :csv).inspect.html_safe %>, \"_brick_schema\", brickSchema), {
310
322
  method: 'PATCH',
311
323
  headers: { 'Content-Type': 'text/tab-separated-values' },
312
324
  body: droppedTSV
@@ -377,17 +389,32 @@ function changeout(href, param, value) {
377
389
  <script async defer src=\"https://apis.google.com/js/api.js\" onload=\"gapiLoaded()\"></script>
378
390
  "
379
391
  end
392
+ # %%% Instead of our current "for Janet Leverling (Employee)" kind of link we previously had this code that did a "where x = 123" thing:
393
+ # (where <%= @_brick_params.each_with_object([]) { |v, s| s << \"#\{v.first\} = #\{v.last.inspect\}\" }.join(', ') %>)
380
394
  "#{css}
381
395
  <p style=\"color: green\"><%= notice %></p>#{"
382
- <select id=\"schema\">#{schema_options}</select>" if ::Brick.db_schemas.length > 1}
396
+ <select id=\"schema\">#{schema_options}</select>" if ::Brick.config.schema_behavior[:multitenant] && ::Brick.db_schemas.length > 1}
383
397
  <select id=\"tbl\">#{table_options}</select>
384
- <h1>#{model_name.pluralize}</h1>#{template_link}
385
-
386
- <% if @_brick_params&.present? %><h3>where <%= @_brick_params.each_with_object([]) { |v, s| s << \"#\{v.first\} = #\{v.last.inspect\}\" }.join(', ') %></h3><% end %>
398
+ <h1>#{model_plural = model_name.pluralize}</h1>#{template_link}
399
+
400
+ <% if @_brick_params&.present? %>
401
+ <% if @_brick_params.length == 1 # %%% Does not yet work with composite keys
402
+ k, id = @_brick_params.first
403
+ id = id.first if id.is_a?(Array) && id.length == 1
404
+ origin = (key_parts = k.split('.')).length == 1 ? #{model_name} : #{model_name}.reflect_on_association(key_parts.first).klass
405
+ # binding.pry
406
+ if (destination_fk = Brick.relations[origin.table_name][:fks].values.find { |fk| puts fk.inspect; fk[:fk] == key_parts.last }) &&
407
+ (obj = (destination = origin.reflect_on_association(destination_fk[:assoc_name])&.klass)&.find(id)) %>
408
+ <h3>for <%= link_to \"#{"#\{obj.brick_descrip\} (#\{destination.name\})\""}, send(\"#\{destination.name.underscore.tr('/', '_')\}_path\".to_sym, id) %></h3><%
409
+ end
410
+ end %>
411
+ (<%= link_to 'See all #{model_plural.split('::').last}', #{path_obj_name.pluralize}_path %>)
412
+ <% end %>
387
413
  <table id=\"#{table_name}\">
388
- <thead><tr>#{'<th></th>' if pk}
414
+ <thead><tr>#{'<th></th>' if pk.present?}
389
415
  <% @#{table_name}.columns.map(&:name).each do |col| %>
390
- <% next if col == '#{pk}' || ::Brick.config.metadata_columns.include?(col) || poly_cols.include?(col) %>
416
+ <% next if (#{(pk || []).inspect}.include?(col) && #{model_name}.column_for_attribute(col).type == :integer && !bts.key?(col)) ||
417
+ ::Brick.config.metadata_columns.include?(col) || poly_cols.include?(col) %>
391
418
  <th>
392
419
  <% if (bt = bts[col]) %>
393
420
  BT <%
@@ -400,15 +427,16 @@ function changeout(href, param, value) {
400
427
  </th>
401
428
  <% end %>
402
429
  <%# Consider getting the name from the association -- h.first.name -- if a more \"friendly\" alias should be used for a screwy table name %>
403
- #{hms_headers.map { |h| "<th>#{h[1]} <%= link_to('#{h[2]}', #{h.first.klass.name.underscore.pluralize}_path) %></th>\n" }.join}
430
+ #{hms_headers.map { |h| "<th>#{h[1]} <%= link_to('#{h[2]}', #{h.first.klass.name.underscore.tr('/', '_').pluralize}_path) %></th>\n" }.join}
404
431
  </tr></thead>
405
432
 
406
433
  <tbody>
407
434
  <% @#{table_name}.each do |#{obj_name}| %>
408
435
  <tr>#{"
409
- <td><%= link_to '⇛', #{obj_name}_path(#{obj_pk}), { class: 'big-arrow' } %></td>" if obj_pk}
436
+ <td><%= link_to '⇛', #{path_obj_name}_path(#{obj_pk}), { class: 'big-arrow' } %></td>" if obj_pk}
410
437
  <% #{obj_name}.attributes.each do |k, val| %>
411
- <% next if k == '#{pk}' || ::Brick.config.metadata_columns.include?(k) || poly_cols.include?(k) || k.start_with?('_brfk_') || (k.start_with?('_br_') && (k.length == 63 || k.end_with?('_ct'))) %>
438
+ <% next if (#{(obj_pk || []).inspect}.include?(k) && #{model_name}.column_for_attribute(k).type == :integer && !bts.key?(k)) ||
439
+ ::Brick.config.metadata_columns.include?(k) || poly_cols.include?(k) || k.start_with?('_brfk_') || (k.start_with?('_br_') && (k.length == 63 || k.end_with?('_ct'))) %>
412
440
  <td>
413
441
  <% if (bt = bts[k]) %>
414
442
  <%# binding.pry # Postgres column names are limited to 63 characters %>
@@ -423,7 +451,7 @@ function changeout(href, param, value) {
423
451
  #{obj_name}, (descrips = @_brick_bt_descrip[bt.first][bt_class])[0..-2].map { |z| #{obj_name}.send(z.last[0..62]) }, (bt_id_col = descrips.last)
424
452
  )
425
453
  bt_id = #{obj_name}.send(*bt_id_col) if bt_id_col&.present? %>
426
- <%= bt_id ? link_to(bt_txt, send(\"#\{bt_class.base_class.name.underscore\}_path\".to_sym, bt_id)) : bt_txt %>
454
+ <%= bt_id ? link_to(bt_txt, send(\"#\{bt_class.base_class.name.underscore.tr('/', '_')\}_path\".to_sym, bt_id)) : bt_txt %>
427
455
  <%#= Previously was: bt_obj = bt[1].first.first.find_by(bt[2] => val); link_to(bt_obj.brick_descrip, send(\"#\{bt[1].first.first.name.underscore\}_path\".to_sym, bt_obj.send(bt[1].first.first.primary_key.to_sym))) if bt_obj %>
428
456
  <% end %>
429
457
  <% else %>
@@ -433,19 +461,19 @@ function changeout(href, param, value) {
433
461
  <% end %>
434
462
  #{hms_columns.each_with_object(+'') { |hm_col, s| s << "<td>#{hm_col}</td>" }}
435
463
  </tr>
436
- </tbody>
437
464
  <% end %>
465
+ </tbody>
438
466
  </table>
439
467
 
440
- #{"<hr><%= link_to \"New #{obj_name}\", new_#{obj_name}_path %>" unless @_brick_model.is_view?}
468
+ #{"<hr><%= link_to \"New #{obj_name}\", new_#{path_obj_name}_path %>" unless @_brick_model.is_view?}
441
469
  #{script}"
442
470
  when 'show', 'update'
443
471
  "#{css}
444
472
  <p style=\"color: green\"><%= notice %></p>#{"
445
- <select id=\"schema\">#{schema_options}</select>" if ::Brick.db_schemas.length > 1}
473
+ <select id=\"schema\">#{schema_options}</select>" if ::Brick.config.schema_behavior[:multitenant] && ::Brick.db_schemas.length > 1}
446
474
  <select id=\"tbl\">#{table_options}</select>
447
475
  <h1>#{model_name}: <%= (obj = @#{obj_name})&.brick_descrip || controller_name %></h1>
448
- <%= link_to '(See all #{obj_name.pluralize})', #{table_name}_path %>
476
+ <%= link_to '(See all #{obj_name.pluralize})', #{path_obj_name.pluralize}_path %>
449
477
  <% if obj %>
450
478
  <%= # path_options = [obj.#{pk}]
451
479
  # path_options << { '_brick_schema': } if
@@ -455,8 +483,8 @@ function changeout(href, param, value) {
455
483
  <% has_fields = false
456
484
  @#{obj_name}.attributes.each do |k, val| %>
457
485
  <tr>
458
- <%# %%% Accommodate composite keys %>
459
- <% next if k == '#{pk}' || ::Brick.config.metadata_columns.include?(k) %>
486
+ <% next if (#{(pk || []).inspect}.include?(k) && !bts.key?(k)) ||
487
+ ::Brick.config.metadata_columns.include?(k) %>
460
488
  <th class=\"show-field\">
461
489
  <% has_fields = true
462
490
  if (bt = bts[k])
@@ -464,26 +492,31 @@ function changeout(href, param, value) {
464
492
  bt_name = bt[1].map { |x| x.first.name }.join('/')
465
493
  # %%% Only do this if the user has permissions to edit this bt field
466
494
  if bt[2] # Polymorphic?
467
- poly_class_name = @#{obj_name}.send(\"#\{bt.first\}_type\")
495
+ poly_class_name = orig_poly_name = @#{obj_name}.send(\"#\{bt.first\}_type\")
468
496
  bt_pair = nil
469
497
  loop do
470
498
  bt_pair = bt[1].find { |pair| pair.first.name == poly_class_name }
471
499
  # Acxommodate any valid STI by going up the chain of inheritance
472
500
  break unless bt_pair.nil? && poly_class_name = ::Brick.existing_stis[poly_class_name]
473
501
  end
502
+ puts \"*** Might be missing an STI class called #\{orig_poly_name\} whose base class should have this:
503
+ *** has_many :#{table_name}, as: :#\{bt.first\}
504
+ *** Can probably auto-configure everything using these lines in an initialiser:
505
+ *** Brick.sti_namespace_prefixes = { '::#\{orig_poly_name\}' => 'SomeParentModel' }
506
+ *** Brick.polymorphics = { '#{table_name}.#\{bt.first\}' => ['SomeParentModel'] }\" if bt_pair.nil?
474
507
  # descrips = @_brick_bt_descrip[bt.first][bt_class]
475
508
  poly_id = @#{obj_name}.send(\"#\{bt.first\}_id\")
476
509
  # bt_class.order(obj_pk = bt_class.primary_key).each { |obj| option_detail << [obj.brick_descrip(nil, obj_pk), obj.send(obj_pk)] }
477
510
  else # No polymorphism, so just get the first one
478
511
  bt_pair = bt[1].first
479
512
  end
480
- bt_class = bt_pair.first
513
+ bt_class = bt_pair&.first
481
514
  if bt.length < 4
482
515
  bt << (option_detail = [[\"(No #\{bt_name\} chosen)\", '^^^brick_NULL^^^']])
483
516
  # %%% Accommodate composite keys for obj.pk at the end here
484
- bt_class.order(obj_pk = bt_class.primary_key).each { |obj| option_detail << [obj.brick_descrip(nil, obj_pk), obj.send(obj_pk)] }
517
+ bt_class&.order(obj_pk = bt_class.primary_key)&.each { |obj| option_detail << [obj.brick_descrip(nil, obj_pk), obj.send(obj_pk)] }
485
518
  end %>
486
- BT <%= bt_class.bt_link(bt.first) %>
519
+ BT <%= bt_class&.bt_link(bt.first) || orig_poly_name %>
487
520
  <% else %>
488
521
  <%= k %>
489
522
  <% end %>
@@ -493,7 +526,7 @@ function changeout(href, param, value) {
493
526
  html_options = { prompt: \"Select #\{bt_name\}\" }
494
527
  html_options[:class] = 'dimmed' unless val %>
495
528
  <%= f.select k.to_sym, bt[3], { value: val || '^^^brick_NULL^^^' }, html_options %>
496
- <%= bt_obj = bt_class.find_by(bt_pair[1] => val); link_to('⇛', send(\"#\{bt_class.base_class.name.underscore\}_path\".to_sym, bt_obj.send(bt_class.primary_key.to_sym)), { class: 'show-arrow' }) if bt_obj %>
529
+ <%= bt_obj = bt_class&.find_by(bt_pair[1] => val); link_to('⇛', send(\"#\{bt_class.base_class.name.underscore.tr('/', '_')\}_path\".to_sym, bt_obj.send(bt_class.primary_key.to_sym)), { class: 'show-arrow' }) if bt_obj %>
497
530
  <% else case #{model_name}.column_for_attribute(k).type
498
531
  when :string, :text %>
499
532
  <% if is_bcrypt?(val) # || .readonly? %>
@@ -535,7 +568,7 @@ function changeout(href, param, value) {
535
568
  <tr><td>(none)</td></tr>
536
569
  <% else %>
537
570
  <% collection.uniq.each do |#{hm_singular_name}| %>
538
- <tr><td><%= link_to(#{hm_singular_name}.brick_descrip, #{hm.first.klass.name.underscore}_path([#{obj_pk}])) %></td></tr>
571
+ <tr><td><%= link_to(#{hm_singular_name}.brick_descrip, #{hm.first.klass.name.underscore.tr('/', '_')}_path([#{obj_pk}])) %></td></tr>
539
572
  <% end %>
540
573
  <% end %>
541
574
  </table>"
@@ -213,7 +213,7 @@ module Brick
213
213
  puts "X3"
214
214
  super(key, ::Brick::JoinArray.new.replace([current, value]))
215
215
  when ::Brick::JoinArray # Concatenate new stuff onto any existing JoinArray
216
- current.set_matching(value, nil)
216
+ current.set_matching(value, nil) if value
217
217
  when ::Brick::JoinHash # Graduate an existing hash into being in an array if things are dissimilar
218
218
  super(key, ::Brick::JoinArray.new.replace([current, value]))
219
219
  value
@@ -5,7 +5,7 @@ module Brick
5
5
  module VERSION
6
6
  MAJOR = 1
7
7
  MINOR = 0
8
- TINY = 27
8
+ TINY = 30
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
@@ -90,10 +90,10 @@ module Brick
90
90
  end
91
91
 
92
92
  class << self
93
- attr_accessor :db_schemas
93
+ attr_accessor :default_schema, :db_schemas
94
94
 
95
95
  def set_db_schema(params)
96
- schema = params['_brick_schema'] || 'public'
96
+ schema = params['_brick_schema']
97
97
  ActiveRecord::Base.execute_sql("SET SEARCH_PATH = ?;", schema) if schema && ::Brick.db_schemas&.include?(schema)
98
98
  end
99
99
 
@@ -287,8 +287,16 @@ module Brick
287
287
  # Database schema to use when analysing existing data, such as deriving a list of polymorphic classes
288
288
  # for polymorphics in which it wasn't originally specified.
289
289
  # @api public
290
- def schema_to_analyse=(schema)
291
- Brick.config.schema_to_analyse = schema
290
+ def schema_behavior=(behavior)
291
+ Brick.config.schema_behavior = (behavior.is_a?(Symbol) ? { behavior => nil } : behavior)
292
+ end
293
+ # For any Brits out there
294
+ def schema_behaviour=(behavior)
295
+ Brick.schema_behavior = behavior
296
+ end
297
+
298
+ def sti_type_column=(type_col)
299
+ Brick.config.sti_type_column = (type_col.is_a?(String) ? { type_col => nil } : type_col)
292
300
  end
293
301
 
294
302
  def default_route_fallback=(resource_name)
@@ -303,18 +311,23 @@ module Brick
303
311
 
304
312
  relations = ::Brick.relations
305
313
  if (ars = ::Brick.config.additional_references) || ::Brick.config.polymorphics
306
- ars.each { |fk| ::Brick._add_bt_and_hm(fk[0..2], relations) } if ars
314
+ if ars
315
+ ars.each do |ar|
316
+ fk = ar.length < 5 ? [nil, +ar[0], ar[1], nil, +ar[2]] : [ar[0], +ar[1], ar[2], ar[3], +ar[4], ar[5]]
317
+ ::Brick._add_bt_and_hm(fk, relations)
318
+ end
319
+ end
307
320
  if (polys = ::Brick.config.polymorphics)
308
- if (schema = ::Brick.config.schema_to_analyse) && ::Brick.db_schemas&.include?(schema)
321
+ if (schema = ::Brick.config.schema_behavior[:multitenant]&.fetch(:schema_to_analyse, nil)) && ::Brick.db_schemas&.include?(schema)
309
322
  ActiveRecord::Base.execute_sql("SET SEARCH_PATH = ?;", schema)
310
323
  end
311
324
  missing_stis = {}
312
325
  polys.each do |k, v|
313
326
  table_name, poly = k.split('.')
314
- v ||= ActiveRecord::Base.execute_sql("SELECT DISTINCT #{poly}_type AS typ FROM #{table_name}").map { |result| result['typ'] }
327
+ v ||= ActiveRecord::Base.execute_sql("SELECT DISTINCT #{poly}_type AS typ FROM #{table_name}").each_with_object([]) { |result, s| s << result['typ'] if result['typ'] }
315
328
  v.each do |type|
316
329
  if relations.key?(primary_table = type.underscore.pluralize)
317
- ::Brick._add_bt_and_hm([table_name, poly, primary_table, "(brick) #{table_name}_#{poly}"], relations, true)
330
+ ::Brick._add_bt_and_hm([nil, table_name, poly, nil, primary_table, "(brick) #{table_name}_#{poly}"], relations, true)
318
331
  else
319
332
  missing_stis[primary_table] = type unless ::Brick.existing_stis.key?(type)
320
333
  end
@@ -325,9 +338,9 @@ module Brick
325
338
  You might be missing an STI namespace prefix entry for these tables: #{missing_stis.keys.join(', ')}.
326
339
  In config/initializers/brick.rb appropriate entries would look something like:
327
340
  Brick.sti_namespace_prefixes = {"
328
- puts missing_stis.map { |_k, missing_sti| "\n '::#{missing_sti}' => 'YourParentModel'" }.join(',')
341
+ puts missing_stis.map { |_k, missing_sti| "\n '::#{missing_sti}' => 'SomeParentModel'" }.join(',')
329
342
  puts " }
330
- (Just trade out YourParentModel with some more appropriate one.)"
343
+ (Just trade out SomeParentModel with some more appropriate one.)"
331
344
  end
332
345
  end
333
346
  @_additional_references_loaded = true
@@ -390,11 +403,20 @@ In config/initializers/brick.rb appropriate entries would look something like:
390
403
  end
391
404
  # %%% TODO: If no auto-controllers then enumerate the controllers folder in order to build matching routes
392
405
  # If auto-controllers and auto-models are both enabled then this makes sense:
393
- ::Brick.relations.each do |k, v|
394
- unless existing_controllers.key?(controller_name = k.underscore.pluralize)
406
+ ::Brick.relations.each do |rel_name, v|
407
+ rel_name = rel_name.split('.').map(&:underscore)
408
+ schema_names = rel_name[0..-2]
409
+ k = rel_name.last
410
+ unless existing_controllers.key?(controller_name = k.pluralize)
395
411
  options = {}
396
412
  options[:only] = [:index, :show] if v.key?(:isView)
397
- send(:resources, controller_name.to_sym, **options)
413
+ if schema_names.present? # && !Object.const_defined('Apartment')
414
+ send(:namespace, schema_names.first) do
415
+ send(:resources, controller_name.to_sym, **options)
416
+ end
417
+ else
418
+ send(:resources, controller_name.to_sym, **options)
419
+ end
398
420
  end
399
421
  end
400
422
  end
@@ -451,7 +473,7 @@ ActiveSupport.on_load(:active_record) do
451
473
  relation = clone # spawn
452
474
  relation.select_values = column_names
453
475
  result = if klass.connection.class.name.end_with?('::PostgreSQLAdapter')
454
- rslt = klass.connection.execute(relation.arel.to_sql)
476
+ rslt = klass.execute_sql(relation.arel.to_sql)
455
477
  rslt.type_map =
456
478
  @type_map ||= proc do
457
479
  # This aliasing avoids the warning:
@@ -113,24 +113,24 @@ module Brick
113
113
  # # #{resembles_fks.join(', ')}"
114
114
  end
115
115
 
116
- poly = case (possible_polymorphics = possible_polymorphics.values.flatten).length
116
+ poly = case (possible_polymorphics = possible_polymorphics.values.flatten.map { |poss_poly| "#{poss_poly} => nil"}).length
117
117
  when 0
118
118
  " like this:
119
- # Brick.polymorphics = [
120
- # 'comments.commentable',
121
- # 'images.imageable'
122
- # ]"
119
+ # Brick.polymorphics = {
120
+ # 'comments.commentable' => nil,
121
+ # 'images.imageable' => nil
122
+ # }"
123
123
  when 1
124
124
  ".
125
125
  # # Here is a possible polymorphic association that has been auto-identified for the #{ActiveRecord::Base.connection.current_database} database:
126
- # Brick.polymorphics = [#{possible_additional_references.first}]"
126
+ # Brick.polymorphics = { #{possible_additional_references.first} }"
127
127
 
128
128
  else
129
129
  ".
130
130
  # # Here are possible polymorphic associations that have been auto-identified for the #{ActiveRecord::Base.connection.current_database} database:
131
- # Brick.polymorphics = [
131
+ # Brick.polymorphics = {
132
132
  # #{possible_polymorphics.join(",\n# ")}
133
- # ]"
133
+ # }"
134
134
  end
135
135
 
136
136
  create_file(filename, "# frozen_string_literal: true
@@ -215,9 +215,15 @@ module Brick
215
215
  # Brick.sti_namespace_prefixes = { '::Animals::' => 'Animal',
216
216
  # '::Snake' => 'Reptile' }
217
217
 
218
+ # # Custom inheritance_column to be used for STI. This is by default \"type\", and applies to all models. With this
219
+ # # option you can change this either for specific models, or apply a new overall name generally:
220
+ # Brick.sti_type_column = 'sti_type'
221
+ # Brick.sti_type_column = { 'rails_type' => ['sales.specialoffer'] }
222
+
218
223
  # # Database schema to use when analysing existing data, such as deriving a list of polymorphic classes in the case that
219
224
  # # it wasn't originally specified.
220
- # Brick.schema_to_analyse = 'engineering'
225
+ # Brick.schema_behavior = :namespaced
226
+ # Brick.schema_behavior = { multitenant: { schema_to_analyse: 'engineering' } }
221
227
 
222
228
  # # Polymorphic associations are set up by providing a model name and polymorphic association name#{poly}
223
229
 
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.27
4
+ version: 1.0.30
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-05-22 00:00:00.000000000 Z
11
+ date: 2022-05-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord