brick 1.0.48 → 1.0.49

Sign up to get free protection for your applications and to get access to all the features.
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