brick 1.0.48 → 1.0.49

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c9c3989f395bc81df36b3f295c72029e92911bd24f8d146db5627fb29c1875f4
4
- data.tar.gz: 97ae12a1562f9f9bae5f401016e219a5ad58218068f80d7fc0e732d61c4f3f90
3
+ metadata.gz: 8b42f1ad45e6dc942ed2e875d39318f8705f9a467c0cb31f267a71a01053bfd4
4
+ data.tar.gz: 1e8f0cd1c374c5d75be4e4f1a8b659dd32b46f991c85cce4d234a6949d017e4b
5
5
  SHA512:
6
- metadata.gz: c64d02f90b992640698523190a920467204a2fbb40fb9e21a3e7872ae469db3506bdf7fb535e54cd33157feb93ed43c2d1c11b2bea952bc9f034ac7e7dfb6b06
7
- data.tar.gz: 6c01156b2b35f387e531ed6835a7517f5249b72ec53bb23d5d965c4b298a443d9a62e5694f9c1b4587f6ab04ef30590d7d9077e13c66b651ee8ed12b76282932
6
+ metadata.gz: 437d415278f01a2ffced31687f77324c21416e6e7ef395d6a5d3db5a1853ccfb301c01716747ba4427417164a1200100205e7b7c75443bef83f1050f01683dda
7
+ data.tar.gz: d42367f291f2900876c5263aab30280f7b5b3d9f205c4199349b9e24d35326b5457e1db8fd0d39a512f59af9691bbe44e29dd05d3384d5a0013c05ffe6447d8c
data/lib/brick/config.rb CHANGED
@@ -190,6 +190,30 @@ module Brick
190
190
  @mutex.synchronize { @table_name_prefixes = value }
191
191
  end
192
192
 
193
+ def order
194
+ @mutex.synchronize { @order || {} }
195
+ end
196
+
197
+ # Get something like:
198
+ # Override how code sorts with:
199
+ # { 'on_call_list' => { code: "ORDER BY STRING_TO_ARRAY(code, '.')::int[]" } }
200
+ # Specify default thing to order_by with:
201
+ # { 'on_call_list' => { _brick_default: [:last_name, :first_name] } }
202
+ # { 'on_call_list' => { _brick_default: :sequence } }
203
+ def order=(orders)
204
+ @mutex.synchronize do
205
+ case (brick_default = orders.fetch(:_brick_default, nil))
206
+ when NilClass
207
+ orders[:_brick_default] = orders.keys.reject { |k| k == :_brick_default }.first
208
+ when String
209
+ orders[:_brick_default] = [brick_default.to_sym]
210
+ when Symbol
211
+ orders[:_brick_default] = [brick_default]
212
+ end
213
+ @order = orders
214
+ end
215
+ end
216
+
193
217
  def metadata_columns
194
218
  @mutex.synchronize { @metadata_columns }
195
219
  end
@@ -221,6 +221,62 @@ module ActiveRecord
221
221
  template
222
222
  end
223
223
 
224
+ # belongs_to DSL descriptions
225
+ def self._br_bt_descrip
226
+ @_br_bt_descrip ||= {}
227
+ end
228
+ # has_many count definitions
229
+ def self._br_hm_counts
230
+ @_br_hm_counts ||= {}
231
+ end
232
+
233
+ # Search for BT, HM, and HMT DSL stuff
234
+ def self._brick_calculate_bts_hms(translations, join_array)
235
+ bts, hms, associatives = ::Brick.get_bts_and_hms(self)
236
+ bts.each do |_k, bt|
237
+ next if bt[2] # Polymorphic?
238
+
239
+ # join_array will receive this relation name when calling #brick_parse_dsl
240
+ _br_bt_descrip[bt.first] = if bt[1].is_a?(Array)
241
+ bt[1].each_with_object({}) { |bt_class, s| s[bt_class] = bt_class.brick_parse_dsl(join_array, bt.first, translations, true) }
242
+ else
243
+ { bt.last => bt[1].brick_parse_dsl(join_array, bt.first, translations) }
244
+ end
245
+ end
246
+ skip_klass_hms = ::Brick.config.skip_index_hms[self.name] || {}
247
+ hms.each do |k, hm|
248
+ next if skip_klass_hms.key?(k)
249
+
250
+ if hm.macro == :has_one
251
+ # For our purposes a :has_one is similar enough to a :belongs_to that we can just join forces
252
+ _br_bt_descrip[k] = { hm.klass => hm.klass.brick_parse_dsl(join_array, k, translations) }
253
+ else # Standard :has_many
254
+ _br_hm_counts[k] = hm
255
+ end
256
+ end
257
+ end
258
+
259
+ def self._brick_calculate_ordering(ordering, is_do_txt = true)
260
+ quoted_table_name = table_name.split('.').map { |x| "\"#{x}\"" }.join('.')
261
+ order_by_txt = [] if is_do_txt
262
+ ordering = [ordering] if ordering && !ordering.is_a?(Array)
263
+ order_by = ordering&.map do |ord_part| # %%% If a term is also used as an eqi-condition in the WHERE clause, it can be omitted from ORDER BY
264
+ case ord_part
265
+ when String
266
+ ord_expr = ord_part.gsub('^^^', quoted_table_name)
267
+ order_by_txt&.<<("Arel.sql(#{ord_expr})")
268
+ Arel.sql(ord_expr)
269
+ else # Expecting only Symbol
270
+ ord_part = "_br_#{ord_part}_ct" if _br_hm_counts.key?(ord_part)
271
+ # Retain any reference to a bt_descrip as being a symbol
272
+ # Was: "#{quoted_table_name}.\"#{ord_part}\""
273
+ order_by_txt&.<<(_br_bt_descrip.key?(ord_part) ? ord_part : ord_part.inspect)
274
+ ord_part
275
+ end
276
+ end
277
+ [order_by, order_by_txt]
278
+ end
279
+
224
280
  private
225
281
 
226
282
  def self._brick_get_fks
@@ -310,13 +366,12 @@ module ActiveRecord
310
366
  end
311
367
  end
312
368
 
313
- def brick_select(params, selects = nil, bt_descrip = {}, hm_counts = {}, join_array = ::Brick::JoinArray.new
314
- # , is_add_bts, is_add_hms
315
- )
316
- is_add_bts = is_add_hms = true
369
+ def brick_select(params, selects = nil, order_by = nil, translations = {}, join_array = ::Brick::JoinArray.new)
317
370
  is_distinct = nil
318
371
  wheres = {}
319
372
  params.each do |k, v|
373
+ next if ['_brick_schema', '_brick_order'].include?(k)
374
+
320
375
  case (ks = k.split('.')).length
321
376
  when 1
322
377
  next unless klass._brick_get_fks.include?(k)
@@ -345,33 +400,6 @@ module ActiveRecord
345
400
  end
346
401
  end
347
402
 
348
- # Search for BT, HM, and HMT DSL stuff
349
- translations = {}
350
- if is_add_bts || is_add_hms
351
- bts, hms, associatives = ::Brick.get_bts_and_hms(klass)
352
- bts.each do |_k, bt|
353
- next if bt[2] # Polymorphic?
354
-
355
- # join_array will receive this relation name when calling #brick_parse_dsl
356
- bt_descrip[bt.first] = if bt[1].is_a?(Array)
357
- bt[1].each_with_object({}) { |bt_class, s| s[bt_class] = bt_class.brick_parse_dsl(join_array, bt.first, translations, true) }
358
- else
359
- { bt.last => bt[1].brick_parse_dsl(join_array, bt.first, translations) }
360
- end
361
- end
362
- skip_klass_hms = ::Brick.config.skip_index_hms[klass.name] || {}
363
- hms.each do |k, hm|
364
- next if skip_klass_hms.key?(k)
365
-
366
- if hm.macro == :has_one
367
- # For our purposes a :has_one is similar enough to a :belongs_to that we can just join forces
368
- bt_descrip[k] = { hm.klass => hm.klass.brick_parse_dsl(join_array, k, translations) }
369
- else # Standard :has_many
370
- hm_counts[k] = hm
371
- end
372
- end
373
- end
374
-
375
403
  if join_array.present?
376
404
  left_outer_joins!(join_array)
377
405
  # Without working from a duplicate, touching the AREL ast tree sets the @arel instance variable, which causes the relation to be immutable.
@@ -380,7 +408,7 @@ module ActiveRecord
380
408
  chains = rel_dupe._brick_chains
381
409
  id_for_tables = Hash.new { |h, k| h[k] = [] }
382
410
  field_tbl_names = Hash.new { |h, k| h[k] = {} }
383
- bt_columns = bt_descrip.each_with_object([]) do |v, s|
411
+ bt_columns = klass._br_bt_descrip.each_with_object([]) do |v, s|
384
412
  v.last.each do |k1, v1| # k1 is class, v1 is array of columns to snag
385
413
  next if chains[k1].nil?
386
414
 
@@ -416,7 +444,7 @@ module ActiveRecord
416
444
  end
417
445
  end
418
446
  # Add derived table JOIN for the has_many counts
419
- hm_counts.each do |k, hm|
447
+ klass._br_hm_counts.each do |k, hm|
420
448
  associative = nil
421
449
  count_column = if hm.options[:through]
422
450
  fk_col = (associative = associatives[hm.name])&.foreign_key
@@ -450,12 +478,31 @@ JOIN (SELECT #{selects.join(', ')}, COUNT(#{'DISTINCT ' if hm.options[:through]}
450
478
  joins!("#{join_clause} ON #{on_clause.join(' AND ')}")
451
479
  end
452
480
  where!(wheres) unless wheres.empty?
481
+ # Must parse the order_by and see if there are any symbols which refer to BT associations
482
+ # as they must be expanded to find the corresponding _br_model__column naming for each.
483
+ if order_by.present?
484
+ final_order_by = *order_by.each_with_object([]) do |v, s|
485
+ if v.is_a?(Symbol)
486
+ # Add the ordered series of columns derived from the BT based on its DSL
487
+ if (bt_cols = klass._br_bt_descrip[v])
488
+ bt_cols.values.each do |v1|
489
+ v1.each { |v2| s << v2.last if v2.length > 1 }
490
+ end
491
+ else
492
+ s << v
493
+ end
494
+ else # String stuff just comes straight through
495
+ s << v
496
+ end
497
+ end
498
+ order!(*final_order_by)
499
+ end
453
500
  limit!(1000) # Don't want to get too carried away just yet
454
501
  wheres unless wheres.empty? # Return the specific parameters that we did use
455
502
  end
456
503
 
457
504
  private
458
-
505
+
459
506
  def shift_or_first(ary)
460
507
  ary.length > 1 ? ary.shift : ary.first
461
508
  end
@@ -926,21 +973,26 @@ class Object
926
973
  (namespace || Object).const_set(class_name.to_sym, new_controller_class)
927
974
 
928
975
  # Brick-specific pages
929
- if plural_class_name == 'BrickGem'
976
+ case plural_class_name
977
+ when 'BrickGem'
930
978
  self.define_method :orphans do
931
979
  instance_variable_set(:@orphans, ::Brick.find_orphans(::Brick.set_db_schema(params)))
932
980
  end
933
981
  return [new_controller_class, code + ' # BrickGem controller']
982
+ when 'BrickSwagger'
983
+ is_swagger = true # if request.format == :json)
934
984
  end
935
985
 
936
- unless (is_swagger = plural_class_name == 'BrickSwagger') # && request.format == :json)
937
- code << " def index\n"
938
- code << " @#{table_name} = #{model.name}#{pk&.present? ? ".order(#{pk.inspect})" : '.all'}\n"
939
- code << " @#{table_name}.brick_select(params)\n"
940
- code << " end\n"
941
- end
942
986
  self.protect_from_forgery unless: -> { self.request.format.js? }
943
987
  self.define_method :index do
988
+ # We do all of this now so that bt_descrip and hm_counts are available on the model early in case the user
989
+ # wants to do an ORDER BY based on any of that
990
+ translations = {}
991
+ join_array = ::Brick::JoinArray.new
992
+ is_add_bts = is_add_hms = true
993
+ # This builds out bt_descrip and hm_counts on the model
994
+ model._brick_calculate_bts_hms(translations, join_array) if is_add_bts || is_add_hms
995
+
944
996
  if is_swagger
945
997
  json = { 'openapi': '3.0.1', 'info': { 'title': 'API V1', 'version': 'v1' },
946
998
  'servers': [
@@ -990,6 +1042,32 @@ class Object
990
1042
  render inline: json.to_json, content_type: request.format
991
1043
  return
992
1044
  end
1045
+
1046
+ # Normal (non-swagger) request
1047
+
1048
+ # %%% Allow params to define which columns to use for order_by
1049
+ ordering = if (order_tbl = ::Brick.config.order[table_name])
1050
+ case (order_default = order_tbl[:_brick_default])
1051
+ when Array
1052
+ order_default.map { |od_part| order_tbl[od_part] || od_part }
1053
+ when Symbol
1054
+ order_tbl[order_default] || order_default
1055
+ else
1056
+ pk
1057
+ end
1058
+ else
1059
+ pk # If it's not a custom ORDER BY, just use the key
1060
+ end
1061
+ order_by, order_by_txt = model._brick_calculate_ordering(ordering)
1062
+ if (order_params = params['_brick_order']&.split(',')&.map(&:to_sym)) # Overriding the default by providing a querystring param?
1063
+ order_by, _ = model._brick_calculate_ordering(order_params, true) # Don't do the txt part
1064
+ end
1065
+
1066
+ code << " def index\n"
1067
+ code << " @#{table_name} = #{model.name}#{pk&.present? ? ".order(#{order_by_txt.join(', ')})" : '.all'}\n"
1068
+ code << " @#{table_name}.brick_select(params)\n"
1069
+ code << " end\n"
1070
+
993
1071
  ::Brick.set_db_schema(params)
994
1072
  if request.format == :csv # Asking for a template?
995
1073
  require 'csv'
@@ -1003,19 +1081,16 @@ class Object
1003
1081
  return
1004
1082
  end
1005
1083
 
1006
- quoted_table_name = model.table_name.split('.').map { |x| "\"#{x}\"" }.join('.')
1007
- order = pk.each_with_object([]) { |pk_part, s| s << "#{quoted_table_name}.\"#{pk_part}\"" }
1008
- ar_relation = order.present? ? model.order("#{order.join(', ')}") : model.all
1009
- @_brick_params = ar_relation.brick_select(params, (selects = []), (bt_descrip = {}), (hm_counts = {}), (join_array = ::Brick::JoinArray.new))
1084
+ @_brick_params = (ar_relation = model.all).brick_select(params, (selects = []), order_by, translations, join_array)
1010
1085
  # %%% Add custom HM count columns
1011
1086
  # %%% What happens when the PK is composite?
1012
- counts = hm_counts.each_with_object([]) { |v, s| s << "_br_#{v.first}._ct_ AS _br_#{v.first}_ct" }
1087
+ counts = model._br_hm_counts.each_with_object([]) { |v, s| s << "_br_#{v.first}._ct_ AS _br_#{v.first}_ct" }
1013
1088
  instance_variable_set("@#{table_name}".to_sym, ar_relation.dup._select!(*selects, *counts))
1014
1089
  if namespace && (idx = lookup_context.prefixes.index(table_name))
1015
1090
  lookup_context.prefixes[idx] = "#{namespace.name.underscore}/#{lookup_context.prefixes[idx]}"
1016
1091
  end
1017
- @_brick_bt_descrip = bt_descrip
1018
- @_brick_hm_counts = hm_counts
1092
+ @_brick_bt_descrip = model._br_bt_descrip
1093
+ @_brick_hm_counts = model._br_hm_counts
1019
1094
  @_brick_join_array = join_array
1020
1095
  end
1021
1096
 
@@ -33,6 +33,9 @@ module Brick
33
33
  # Additional references (virtual foreign keys)
34
34
  ::Brick.additional_references = app.config.brick.fetch(:additional_references, nil)
35
35
 
36
+ # When table names have specific prefixes, automatically place them in their own module with a table_name_prefix.
37
+ ::Brick.order = app.config.brick.fetch(:order, {})
38
+
36
39
  # Skip creating a has_many association for these
37
40
  ::Brick.exclude_hms = app.config.brick.fetch(:exclude_hms, nil)
38
41
 
@@ -199,6 +202,9 @@ table thead tr th, table tr th {
199
202
  color: #fff;
200
203
  text-align: left;
201
204
  }
205
+ #headerTop th:hover, #headerTop th:hover {
206
+ background-color: #18B090;
207
+ }
202
208
  table thead tr th a, table tr th a {
203
209
  color: #80FFB8;
204
210
  }
@@ -547,30 +553,33 @@ if (headerTop) {
547
553
  <br>
548
554
  <table id=\"headerTop\">
549
555
  <table id=\"#{table_name}\">
550
- <thead><tr>#{'<th></th>' if pk.present?}<%
556
+ <thead><tr>#{"<th x-order=\"#{pk.join(',')}\"></th>" if pk.present?}<%
551
557
  col_order = []
552
558
  @#{table_name}.columns.each do |col|
553
559
  next if (#{(pk || []).inspect}.include?(col_name = col.name) && col.type == :integer && !bts.key?(col_name)) ||
554
560
  ::Brick.config.metadata_columns.include?(col_name) || poly_cols.include?(col_name)
555
561
 
556
562
  col_order << col_name
557
- %><th<%= \" title = \\\"#\{col.comment}\\\"\".html_safe if col.respond_to?(:comment) && !col.comment.blank? %>><%
563
+ %><th<%= \" title=\\\"#\{col.comment}\\\"\".html_safe if col.respond_to?(:comment) && !col.comment.blank? %><%
558
564
  if (bt = bts[col_name]) %>
559
- BT <%
565
+ <%= \" x-order=\\\"#\{bt.first}\\\"\".html_safe if true # Currently we always allow click to sort
566
+ %>>BT <%
560
567
  bt[1].each do |bt_pair| %><%=
561
568
  bt_pair.first.bt_link(bt.first) %> <%
562
569
  end %><%
563
- else %><%=
564
- col_name %><%
570
+ else %><%= \" x-order=\\\"#\{col_name}\\\"\".html_safe if true # Currently we always allow click to sort
571
+ %>><%= col_name %><%
565
572
  end
566
573
  %></th><%
567
574
  end
568
575
  # Consider getting the name from the association -- h.first.name -- if a more \"friendly\" alias should be used for a screwy table name
569
576
  %>#{hms_headers.map do |h|
577
+ # Currently we always allow click to sort
578
+ "<th#{" x-order=\"#{h.first.name}\"" if true}>" +
570
579
  if h.first.options[:through] && !h.first.through_reflection
571
- "<th>#{h[1]} #{h[2]} %></th>" # %%% Would be able to remove this when multiple foreign keys to same destination becomes bulletproof
580
+ "#{h[1]} #{h[2]} %></th>" # %%% Would be able to remove this when multiple foreign keys to same destination becomes bulletproof
572
581
  else
573
- "<th>#{h[1]} <%= link_to('#{h[2]}', #{h.first.klass.name.underscore.tr('/', '_').pluralize}_path) %></th>"
582
+ "#{h[1]} <%= link_to('#{h[2]}', #{h.first.klass.name.underscore.tr('/', '_').pluralize}_path) %></th>"
574
583
  end
575
584
  end.join
576
585
  }</tr></thead>
@@ -658,7 +667,7 @@ end
658
667
  <tr>
659
668
  <% next if (#{(pk || []).inspect}.include?(k) && !bts.key?(k)) ||
660
669
  ::Brick.config.metadata_columns.include?(k) %>
661
- <th class=\"show-field\"<%= \" title = \\\"#\{col.comment}\\\"\".html_safe if col.respond_to?(:comment) && !col.comment.blank? %>>
670
+ <th class=\"show-field\"<%= \" title=\\\"#\{col.comment}\\\"\".html_safe if col.respond_to?(:comment) && !col.comment.blank? %>>
662
671
  <% has_fields = true
663
672
  if (bt = bts[k])
664
673
  # Add a final member in this array with descriptive options to be used in <select> drop-downs
@@ -729,9 +738,14 @@ end
729
738
  <% when :uuid %>
730
739
  <%=
731
740
  # Postgres naturally uses the +uuid_generate_v4()+ function from the uuid-ossp extension
732
- # If it's not yet enabled then: enable_extension 'uuid-ossp'
741
+ # If it's not yet enabled then: create extension \"uuid-ossp\";
733
742
  # ActiveUUID gem created a new :uuid type
734
743
  val %>
744
+ <% when :ltree %>
745
+ <%=
746
+ # In Postgres labels of data stored in a hierarchical tree-like structure
747
+ # If it's not yet enabled then: create extension ltree;
748
+ val %>
735
749
  <% when :binary, :primary_key %>
736
750
  <% end %>
737
751
  <% end %>
@@ -789,6 +803,13 @@ flatpickr(\".timepicker\", {enableTime: true, noCalendar: true});
789
803
  </script>
790
804
  <% end %>
791
805
  <script>
806
+ <% # Make column headers sort when clicked
807
+ # %%% Create a smart javascript routine which can do this client-side %>
808
+ [... document.getElementsByTagName(\"TH\")].forEach(function (th) {
809
+ th.addEventListener(\"click\", function (e) {
810
+ location.href = changeout(location.href, \"_brick_order\", this.getAttribute(\"x-order\"));
811
+ });
812
+ });
792
813
  document.querySelectorAll(\"input, select\").forEach(function (inp) {
793
814
  var origVal = getInpVal(),
794
815
  prevVal = origVal;
@@ -5,7 +5,7 @@ module Brick
5
5
  module VERSION
6
6
  MAJOR = 1
7
7
  MINOR = 0
8
- TINY = 48
8
+ TINY = 49
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
@@ -283,6 +283,11 @@ module Brick
283
283
  end
284
284
  end
285
285
 
286
+ # @api public
287
+ def order=(value)
288
+ Brick.config.order = value
289
+ end
290
+
286
291
  # Skip creating a has_many association for these
287
292
  # (Uses the same exact three-part format as would define an additional_reference)
288
293
  # @api public
@@ -159,6 +159,41 @@ module Brick
159
159
  # # When table names have specific prefixes automatically place them in their own module with a table_name_prefix.
160
160
  # Brick.table_name_prefixes = { 'nav_' => 'Navigation' }
161
161
 
162
+ # # COLUMN SEQUENCING AND INCLUSION / EXCLUSION
163
+
164
+ # # By default if there is a primary key present then rows in an index view are ordered by this primary key. To
165
+ # # use a different rule for doing ORDER BY, you can override this default ordering done by The Brick, for instance
166
+ # # to have the rows in a contact list sorted by email:
167
+ # Brick.order = { 'contacts' => { _brick_default: :email } }
168
+ # # or by last name then first name:
169
+ # Brick.order = { 'contacts' => { _brick_default: [:lastname, :firstname] } }
170
+ # # Totally legitimate to have the default order be the name of a belongs_to or has_many association instead of an
171
+ # # actual column name, in which case for has_many it just orders by the count of how many records are associated,
172
+ # # and for belongs_to it's based on the primary table's DSL if any is defined (since that is what is used to
173
+ # # calculate what is shown when a foreign table lists out related records). If contacts relates to addresses,
174
+ # # then this is perfectly fine:
175
+ # Brick.order = { 'contacts' => { _brick_default: :address } }
176
+ # # You can even have a specific custom clause used in the ORDER BY. In this case it is recommended to include a
177
+ # # special placeholder for the table name with the sequence \"^^^\". Here is an example of having the default
178
+ # # ordering happening on the \"code\" column, and also defining custom sorting to be done, in this case proper
179
+ # # ordering if that code is stored as a dotted numeric value:
180
+ # Brick.order = { 'document_trees' => { _brick_default: :code,
181
+ # code: \"ORDER BY STRING_TO_ARRAY(^^^.code, '.')::int[]\" } }
182
+
183
+ # # Sequence of columns for each model. This also allows you to add read-only calculated columns in the same
184
+ # # kind of way that they can be added in the include: portion of include/exclude columns, below.
185
+ # # Designated by { <table name> => [<column name>, <column name>] }
186
+ # Brick.column_sequence = { 'users' => ['email', 'profile.firstname', 'profile.lastname'] }
187
+
188
+ # # Specific columns to include or exclude for each model. If there are only inclusions then only those
189
+ # # columns show. If there are any exclusions then all non-excluded columns are attempted to be shown,
190
+ # # which negates the usefulness of inclusions except to add calculated column detail built from DSL.
191
+ # # Designated by <table name>.<column name>
192
+ # Brick.column_sequence = { 'users' => { include: ['email', 'profile.firstname', 'profile.lastname'] },
193
+ # 'profile' => { exclude: ['birthdate'] } }
194
+
195
+ # # EXTRA FOREIGN KEYS AND OTHER HAS_MANY SETTINGS
196
+
162
197
  # # Additional table references which are used to create has_many / belongs_to associations inside auto-created
163
198
  # # models. (You can consider these to be \"virtual foreign keys\" if you wish)... You only have to add these
164
199
  # # in cases where your database for some reason does not have foreign key constraints defined. Sometimes for
@@ -176,8 +211,9 @@ module Brick
176
211
  # Brick.exclude_hms = [['users', 'favourite_colour_id', 'colours']]
177
212
 
178
213
  # # Skip showing counts for these specific has_many associations when building auto-generated #index views.
179
- # # When there are related tables with a significant number of records, this can lessen the load on the database
180
- # # considerably, sometimes fixing what might appear to be an index page that just \"hangs\" for no apparent reason.
214
+ # # When there are related tables with a significant number of records (generally 100,000 or more), this can lessen
215
+ # # the load on the database considerably, sometimes fixing what might appear to be an index page that just \"hangs\"
216
+ # # for no apparent reason.
181
217
  # Brick.skip_index_hms = ['User.litany_of_woes']
182
218
 
183
219
  # # By default primary tables involved in a foreign key relationship will indicate a \"has_many\" relationship pointing
@@ -199,6 +235,8 @@ module Brick
199
235
  # # Designated by <table name>.<column name>
200
236
  # Brick.not_nullables = ['users.name']
201
237
 
238
+ # # FRIENDLY DSL
239
+
202
240
  # # A simple DSL is available to allow more user-friendly display of objects. Normally a user object might be shown
203
241
  # # as its first non-metadata column, or if that is not available then something like \"User #45\" where 45 is that
204
242
  # # object's ID. If there is no primary key then even that is not possible, so the object's .to_s method is called.
@@ -206,6 +244,8 @@ module Brick
206
244
  # # user, then you can use model_descrips like this, putting expressions with property references in square brackets:
207
245
  # Brick.model_descrips = { 'User' => '[profile.firstname] [profile.lastname]' }
208
246
 
247
+ # # SINGLE TABLE INHERITANCE
248
+
209
249
  # # Specify STI subclasses either directly by name or as a general module prefix that should always relate to a specific
210
250
  # # parent STI class. The prefixed :: here for these examples is mandatory. Also having a suffixed :: means instead of
211
251
  # # a class reference, this is for a general namespace reference. So in this case requests for, say, either of the
@@ -221,6 +261,8 @@ module Brick
221
261
  # Brick.sti_type_column = 'sti_type'
222
262
  # Brick.sti_type_column = { 'rails_type' => ['sales.specialoffer'] }
223
263
 
264
+ # # POLYMORPHIC ASSOCIATIONS
265
+
224
266
  # # Database schema to use when analysing existing data, such as deriving a list of polymorphic classes in the case that
225
267
  # # it wasn't originally specified.
226
268
  # Brick.schema_behavior = :namespaced
@@ -231,6 +273,8 @@ module Brick
231
273
 
232
274
  # # Polymorphic associations are set up by providing a model name and polymorphic association name#{poly}
233
275
 
276
+ # # DEFAULT ROOT ROUTE
277
+
234
278
  # # If a default route is not supplied, Brick attempts to find the most \"central\" table and wires up the default
235
279
  # # route to go to the :index action for what would be a controller for that table. You can specify any controller
236
280
  # # name and action you wish in order to override this and have that be the default route when none other has been
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.48
4
+ version: 1.0.49
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-07-20 00:00:00.000000000 Z
11
+ date: 2022-07-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord