brick 1.0.185 → 1.0.187

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: d930911e6903179271b74220c325ba024dfebe26f87eec06111772bfe1dd6b39
4
- data.tar.gz: fb0767bf7e59c56dffbe1999ee86ca3cefe66040dd26387019f2d45b8776fcd3
3
+ metadata.gz: 72ed0bc43d9ca9ae52dd6641bd5ba400bcb9a4fdb4e13953f931f2b7e1f0d46a
4
+ data.tar.gz: e5e56338e6e980ccfd733697e4cc9efaa8929e38b7f154c8d668ddc784bd55bc
5
5
  SHA512:
6
- metadata.gz: d03584188eaf7ba5a41b37fd80470f6eeb8c166949f4e19f1e2a9ccf958b94d0864c25f16363fbaae1980c36d8e82ec0eacf731cd5bdee97ec819a68be4b9836
7
- data.tar.gz: 5fc2966228117b7d35e5370ff64f2f46e85e8bfa8a1a4a4df8732e91fe0e0f4c0a5050cc7b77d44217538a7bc46681a24ebd03d0fc6ff69f483f7a7861f74a38
6
+ metadata.gz: 06321d9f6ca977150dcc5458d85cb3a329955bbe961b26a273581392e8219bebbc669ad3373d2c57030b0c9b6df07e5c8cef0bdb6bcb7f14379e3ddf73ddb23e
7
+ data.tar.gz: d3432a3ba5983e1ac69d9dde0c5fb6a186d838e32007e0db5ca0af2497f4e918c7f58d9c10db23218c2c7fd605a64e86b50ab8002130845f993fae3a6232a08c
@@ -160,7 +160,7 @@ if ActiveRecord.version < ::Gem::Version.new('5.0') && ::Gem::Version.new(RUBY_V
160
160
  if ::Gem::Version.new(RUBY_VERSION) >= ::Gem::Version.new('3.1')
161
161
  # @@schemes fix for global_id gem < 1.0
162
162
  URI.class_variable_set(:@@schemes, {}) unless URI.class_variables.include?(:@@schemes)
163
- if Gem::Specification.all_names.find { |g| g.start_with?('puma-') }
163
+ if Gem::Dependency.new('puma').matching_specs.present?
164
164
  require 'rack/handler/puma'
165
165
  module Rack::Handler::Puma
166
166
  class << self
@@ -96,38 +96,60 @@ module ActiveRecord
96
96
  end
97
97
  columns_hash.keys.map(&:to_sym) + (rtans || [])
98
98
  end
99
- end
100
99
 
101
- def self._brick_primary_key(relation = nil)
102
- return @_brick_primary_key if instance_variable_defined?(:@_brick_primary_key)
103
-
104
- pk = begin
105
- primary_key.is_a?(String) ? [primary_key] : primary_key.dup || []
106
- rescue
107
- []
108
- end
109
- pk.map! { |pk_part| pk_part =~ /^[A-Z0-9_]+$/ ? pk_part.downcase : pk_part } unless connection.adapter_name == 'MySQL2'
110
- # Just return [] if we're missing any part of the primary key. (PK is usually just "id")
111
- if relation && pk.present?
112
- @_brick_primary_key ||= pk.any? { |pk_part| !relation[:cols].key?(pk_part) } ? [] : pk
113
- else # No definitive key yet, so return what we can without setting the instance variable
114
- pk
100
+ def _br_quoted_name(name)
101
+ if name == '*'
102
+ name
103
+ elsif is_mysql
104
+ "`#{name.gsub('.', '`.`')}`"
105
+ elsif is_postgres || is_mssql
106
+ "\"#{name.gsub('.', '"."')}\""
107
+ else
108
+ name
109
+ end
115
110
  end
116
- end
117
111
 
118
- # Used to show a little prettier name for an object
119
- def self.brick_get_dsl
120
- # If there's no DSL yet specified, just try to find the first usable column on this model
121
- unless (dsl = ::Brick.config.model_descrips[name])
122
- skip_columns = _brick_get_fks + (::Brick.config.metadata_columns || []) + [primary_key]
123
- dsl = if (descrip_col = columns.find { |c| [:boolean, :binary, :xml].exclude?(c.type) && skip_columns.exclude?(c.name) })
124
- "[#{descrip_col.name}]"
125
- elsif (pk_parts = self.primary_key.is_a?(Array) ? self.primary_key : [self.primary_key])
126
- "#{name} ##{pk_parts.map { |pk_part| "[#{pk_part}]" }.join(', ')}"
127
- end
128
- ::Brick.config.model_descrips[name] = dsl
112
+ def is_postgres
113
+ @is_postgres ||= connection.adapter_name == 'PostgreSQL'
114
+ end
115
+ def is_mysql
116
+ @is_mysql ||= ['Mysql2', 'Trilogy'].include?(connection.adapter_name)
117
+ end
118
+ def is_mssql
119
+ @is_mssql ||= connection.adapter_name == 'SQLServer'
120
+ end
121
+
122
+ def _brick_primary_key(relation = nil)
123
+ return @_brick_primary_key if instance_variable_defined?(:@_brick_primary_key)
124
+
125
+ pk = begin
126
+ primary_key.is_a?(String) ? [primary_key] : primary_key.dup || []
127
+ rescue
128
+ []
129
+ end
130
+ pk.map! { |pk_part| pk_part =~ /^[A-Z0-9_]+$/ ? pk_part.downcase : pk_part } unless connection.adapter_name == 'MySQL2'
131
+ # Just return [] if we're missing any part of the primary key. (PK is usually just "id")
132
+ if relation && pk.present?
133
+ @_brick_primary_key ||= pk.any? { |pk_part| !relation[:cols].key?(pk_part) } ? [] : pk
134
+ else # No definitive key yet, so return what we can without setting the instance variable
135
+ pk
136
+ end
137
+ end
138
+
139
+ # Used to show a little prettier name for an object
140
+ def brick_get_dsl
141
+ # If there's no DSL yet specified, just try to find the first usable column on this model
142
+ unless (dsl = ::Brick.config.model_descrips[name])
143
+ skip_columns = _brick_get_fks + (::Brick.config.metadata_columns || []) + [primary_key]
144
+ dsl = if (descrip_col = columns.find { |c| [:boolean, :binary, :xml].exclude?(c.type) && skip_columns.exclude?(c.name) })
145
+ "[#{descrip_col.name}]"
146
+ elsif (pk_parts = self.primary_key.is_a?(Array) ? self.primary_key : [self.primary_key])
147
+ "#{name} ##{pk_parts.map { |pk_part| "[#{pk_part}]" }.join(', ')}"
148
+ end
149
+ ::Brick.config.model_descrips[name] = dsl
150
+ end
151
+ dsl
129
152
  end
130
- dsl
131
153
  end
132
154
 
133
155
  def self.brick_parse_dsl(join_array = nil, prefix = [], translations = {}, is_polymorphic = false, dsl = nil, emit_dsl = false)
@@ -317,10 +339,15 @@ module ActiveRecord
317
339
  tbl_parts[-1] = aps
318
340
  tbl_parts << last_part
319
341
  end
320
- tbl_parts.unshift(::Brick.config.path_prefix) if ::Brick.config.path_prefix
342
+ path_prefix = []
343
+ if ::Brick.config.path_prefix
344
+ tbl_parts.unshift(::Brick.config.path_prefix)
345
+ path_prefix << ::Brick.config.path_prefix
346
+ end
321
347
  index = tbl_parts.map(&:underscore).join(separator)
322
- # Rails applies an _index suffix to that route when the resource name is singular
323
- index << '_index' if mode != :singular && separator == '_' && index == index.singularize
348
+ # Rails applies an _index suffix to that route when the resource name isn't something plural
349
+ index << '_index' if mode != :singular && separator == '_' &&
350
+ index == (path_prefix + [name&.underscore&.tr('/', '_') || '_']).join(separator)
324
351
  index
325
352
  end
326
353
 
@@ -415,15 +442,18 @@ module ActiveRecord
415
442
  end
416
443
 
417
444
  def self._brick_calculate_ordering(ordering, is_do_txt = true)
418
- quoted_table_name = table_name.split('.').map { |x| "\"#{x}\"" }.join('.')
419
445
  order_by_txt = [] if is_do_txt
420
446
  ordering = [ordering] if ordering && !ordering.is_a?(Array)
421
447
  order_by = ordering&.each_with_object([]) do |ord_part, s| # %%% If a term is also used as an eqi-condition in the WHERE clause, it can be omitted from ORDER BY
422
448
  case ord_part
423
449
  when String
424
- ord_expr = ord_part.gsub('^^^', quoted_table_name)
425
- order_by_txt&.<<("Arel.sql(#{ord_expr})")
426
- s << Arel.sql(ord_expr)
450
+ if ord_part.index('^^^')
451
+ ord_expr = ord_part.gsub('^^^', _br_quoted_name(table_name))
452
+ s << Arel.sql(ord_expr)
453
+ else
454
+ s << Arel.sql(_br_quoted_name(ord_expr))
455
+ end
456
+ order_by_txt&.<<("Arel.sql(#{ord_expr.inspect})")
427
457
  else # Expecting only Symbol
428
458
  ord_part = ord_part.to_s
429
459
  if ord_part[0] == '-' # First char '-' means descending order
@@ -433,15 +463,14 @@ module ActiveRecord
433
463
  if ord_part[0] == '~' # Char '~' means order NULLs as highest values instead of lowest
434
464
  ord_part.slice!(0)
435
465
  # (Unfortunately SQLServer does not support NULLS FIRST / NULLS LAST, so leave them out.)
436
- is_nulls_switch = case ActiveRecord::Base.connection.adapter_name
437
- when 'PostgreSQL', 'OracleEnhanced', 'SQLite'
438
- :pg
439
- when 'Mysql2', 'Trilogy'
466
+ is_nulls_switch = if is_mysql
440
467
  :mysql
468
+ else # PostgreSQL, OracleEnhanced, SQLite
469
+ :pg
441
470
  end
442
471
  end
443
472
  if _br_hm_counts.key?(ord_part_sym = ord_part.to_sym)
444
- ord_part = +"\"b_r_#{ord_part}_ct\""
473
+ ord_part = _br_quoted_name("b_r_#{ord_part}_ct")
445
474
  elsif _br_bt_descrip.key?(ord_part_sym)
446
475
  ord_part = _br_bt_descrip.fetch(ord_part_sym, nil)&.first&.last&.first&.last&.dup
447
476
  elsif !_br_cust_cols.key?(ord_part_sym) && !column_names.include?(ord_part)
@@ -1075,28 +1104,6 @@ Might want to add this in your brick.rb:
1075
1104
  def shift_or_first(ary)
1076
1105
  ary.length > 1 ? ary.shift : ary.first
1077
1106
  end
1078
-
1079
- def _br_quoted_name(name)
1080
- if name == '*'
1081
- name
1082
- elsif is_mysql
1083
- "`#{name.gsub('.', '`.`')}`"
1084
- elsif is_postgres || is_mssql
1085
- "\"#{(name).gsub('.', '"."')}\""
1086
- else
1087
- name
1088
- end
1089
- end
1090
-
1091
- def is_postgres
1092
- @is_postgres ||= ActiveRecord::Base.connection.adapter_name == 'PostgreSQL'
1093
- end
1094
- def is_mysql
1095
- @is_mysql ||= ['Mysql2', 'Trilogy'].include?(ActiveRecord::Base.connection.adapter_name)
1096
- end
1097
- def is_mssql
1098
- @is_mssql ||= ActiveRecord::Base.connection.adapter_name == 'SQLServer'
1099
- end
1100
1107
  end
1101
1108
 
1102
1109
  module Inheritance
@@ -1500,7 +1507,8 @@ class Object
1500
1507
  schema_name = ::Brick.apartment_default_tenant
1501
1508
  end
1502
1509
  # Maybe, just maybe there's a database table that will satisfy this need
1503
- if (matching = [table_name, singular_table_name, plural_class_name, model_name, table_name.titleize].find { |m| relations.key?(schema_name ? "#{schema_name}.#{m}" : m) })
1510
+ matching = ::Brick.table_name_lookup&.fetch(class_name, nil)
1511
+ if (matching ||= [table_name, singular_table_name, plural_class_name, model_name, table_name.titleize].find { |m| relations.key?(schema_name ? "#{schema_name}.#{m}" : m) })
1504
1512
  build_model_worker(schema_name, inheritable_name, model_name, singular_table_name, table_name, relations, matching)
1505
1513
  end
1506
1514
  end
@@ -1706,7 +1714,7 @@ class Object
1706
1714
  # options[:class_name] = hm.first[:inverse_table].singularize.camelize
1707
1715
  # options[:foreign_key] = hm.first[:fk].to_sym
1708
1716
  far_assoc = relations[hm.first[:inverse_table]][:fks].find { |_k, v| v[:assoc_name] == hm[1] }
1709
- options[:class_name] = far_assoc.last[:inverse_table].singularize.camelize
1717
+ options[:class_name] = ::Brick.namify(far_assoc.last[:inverse_table], :underscore).camelize
1710
1718
  options[:foreign_key] = far_assoc.last[:fk].to_sym
1711
1719
  end
1712
1720
  options[:source] ||= hm[1].to_sym unless hmt_name.singularize == hm[1]
@@ -1793,7 +1801,9 @@ class Object
1793
1801
  ::Brick.config.schema_behavior[:multitenant] && singular_table_parts.first == 'public'
1794
1802
  singular_table_parts.shift
1795
1803
  end
1796
- options[:class_name] = "::#{assoc[:primary_class]&.name || singular_table_parts.map(&:camelize).join('::')}" if need_class_name
1804
+ options[:class_name] = "::#{assoc[:primary_class]&.name ||
1805
+ singular_table_parts.map { |p| ::Brick.namify(p, :underscore).camelize}.join('::')
1806
+ }" if need_class_name
1797
1807
  if need_fk # Funky foreign key?
1798
1808
  options_fk_key = :foreign_key
1799
1809
  if assoc[:fk].is_a?(Array)
@@ -2044,9 +2054,10 @@ class Object
2044
2054
  _schema, @_is_show_schema_list = ::Brick.set_db_schema(params || api_params)
2045
2055
 
2046
2056
  if is_openapi
2047
- api_name = Rswag::Ui.config.config_object[:urls].find do |api_url|
2048
- api_url[:url] == request.path
2049
- end&.fetch(:name, 'API documentation')
2057
+ doc_endpoints = (Object.const_defined?('Rswag::Ui') &&
2058
+ (::Rswag::Ui.config.config_object[:urls])) ||
2059
+ ::Brick.instance_variable_get(:@swagger_endpoints)
2060
+ api_name = doc_endpoints&.find { |api_url| api_url[:url] == request.path }&.fetch(:name, 'API documentation')
2050
2061
  current_api_ver = current_api_root.split('/').last&.[](1..-1).to_i
2051
2062
  json = { 'openapi': '3.0.1', 'info': { 'title': api_name, 'version': request_ver },
2052
2063
  'servers': [
@@ -2541,10 +2552,14 @@ class Object
2541
2552
  [new_alt_name, true]
2542
2553
  else
2543
2554
  assoc_name = ::Brick.namify(hm_assoc[:inverse_table]).pluralize
2544
- if (needs_class = assoc_name.include?('.')) # If there is a schema name present, use a downcased version for the :has_many
2545
- assoc_parts = assoc_name.split('.')
2555
+ assoc_parts = assoc_name.split('.')
2556
+ if (needs_class = assoc_parts.length > 1) # If there is a schema name present, use a downcased version for the :has_many
2546
2557
  assoc_parts[0].downcase! if assoc_parts[0] =~ /^[A-Z0-9_]+$/
2547
2558
  assoc_name = assoc_parts.join('.')
2559
+ else
2560
+ class_name_parts = ::Brick.namify(hm_assoc[:inverse_table], :underscore).split('.')
2561
+ real_name = class_name_parts.map(&:camelize).join('::')
2562
+ needs_class = (real_name != hm_assoc[:inverse_table].camelize)
2548
2563
  end
2549
2564
  # hm_assoc[:assoc_name] = assoc_name
2550
2565
  [assoc_name, needs_class]
@@ -2954,6 +2969,7 @@ ORDER BY 1, 2, c.internal_column_id, acc.position"
2954
2969
  end
2955
2970
  end
2956
2971
 
2972
+ table_name_lookup = (::Brick.table_name_lookup ||= {})
2957
2973
  relations.each do |k, v|
2958
2974
  next if k.is_a?(Symbol)
2959
2975
 
@@ -2975,7 +2991,9 @@ ORDER BY 1, 2, c.internal_column_id, acc.position"
2975
2991
  v[:resource] = rel_name.last
2976
2992
  [singular]
2977
2993
  end
2978
- v[:class_name] = (schema_names + name_parts).map(&:camelize).join('::')
2994
+ v[:class_name] = (schema_names + name_parts).map { |p| ::Brick.namify(p, :underscore).camelize }.join('::')
2995
+ # Track anything that's out-of-the-ordinary
2996
+ table_name_lookup[v[:class_name]] = k unless v[:class_name].underscore.pluralize == k
2979
2997
  end
2980
2998
  ::Brick.load_additional_references if ::Brick.initializer_loaded
2981
2999
 
@@ -636,7 +636,7 @@ window.addEventListener(\"popstate\", linkSchemas);
636
636
  resource_parts[-1] = class_name # Make sure the last part, defining the class name, is singular
637
637
  begin
638
638
  resource_parts.shift if resource_parts.first == ::Brick.config.path_prefix
639
- if (model = Object.const_get(resource_parts.map(&:camelize).join('::')))&.is_a?(Class) && (
639
+ if (model = Object.const_get(resource_parts.map { |p| ::Brick.namify(p, :underscore).camelize }.join('::')))&.is_a?(Class) && (
640
640
  ['index', 'show'].include?(find_args.first) || # Everything has index and show
641
641
  # Only CUD stuff has create / update / destroy
642
642
  (!model.is_view? && ['new', 'create', 'edit', 'update', 'destroy'].include?(find_args.first))
@@ -5,7 +5,7 @@ module Brick
5
5
  module VERSION
6
6
  MAJOR = 1
7
7
  MINOR = 0
8
- TINY = 185
8
+ TINY = 187
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
@@ -89,7 +89,7 @@ end
89
89
  # is first established), and then automatically creates models, controllers, views,
90
90
  # and routes based on those available relations.
91
91
  require 'brick/config'
92
- if Gem::Specification.all_names.any? { |g| g.start_with?('rails-') && g[6..-1] =~ /^([0-9]|\.)+(?:|rc1|rc2|beta1)$/ }
92
+ if Gem::Dependency.new('rails').matching_specs.present?
93
93
  require 'rails'
94
94
  require 'brick/frameworks/rails'
95
95
  end
@@ -108,7 +108,8 @@ module Brick
108
108
 
109
109
  attr_accessor :default_schema, :db_schemas, :test_schema,
110
110
  :routes_done, :established_drf,
111
- :is_oracle, :is_eager_loading, :auto_models, :initializer_loaded
111
+ :is_oracle, :is_eager_loading, :auto_models, :initializer_loaded,
112
+ :table_name_lookup
112
113
  ::Brick.auto_models = []
113
114
 
114
115
  def get_possible_schemas
@@ -210,12 +211,22 @@ module Brick
210
211
  puts "Based on inclusion in ::Brick.polymorphics, marking association #{full_assoc_name} as being polymorphic."
211
212
  a.options[:polymorphic] = true
212
213
  end
213
- if !a.polymorphic? && (a.belongs_to? || (through = a.options[:through])) &&
214
- !(a.klass && ::Brick.config.exclude_tables.exclude?(a.klass.table_name) &&
214
+ if (through = a.options[:through]) && !a.through_reflection
215
+ puts "WARNING: In model #{model.name}, unable to utilise: has_many #{a.name}, through: #{through.inspect}"
216
+ end
217
+ primary_klass = if a.belongs_to?
218
+ a.polymorphic? ? nil : a.klass
219
+ else
220
+ a.active_record
221
+ end
222
+ a_pk = a.options.fetch(:primary_key, nil)&.to_s ||
223
+ primary_klass&.primary_key # Was: a.klass.primary_key
224
+ if !a.polymorphic? && (a.belongs_to? || (through && (thr = a.through_reflection))) &&
225
+ !((kls = thr&.klass || a.klass) && ::Brick.config.exclude_tables.exclude?(kls.table_name) &&
215
226
  (!a.belongs_to? ||
216
227
  ((fk_type = a.foreign_key.is_a?(Array) ? a.foreign_key.map { |fk_part| model_cols[fk_part.to_s].type } : model_cols[a.foreign_key.to_s].type) &&
217
- (primary_cols = a.klass.columns_hash) &&
218
- (pk_type = a.klass.primary_key.is_a?(Array) ? a.klass.primary_key.map { |pk_part| primary_cols[pk_part.to_s].type } : primary_cols[a.klass.primary_key].type) &&
228
+ (primary_cols = primary_klass.columns_hash) &&
229
+ (pk_type = a_pk.is_a?(Array) ? a_pk.map { |pk_part| primary_cols[pk_part.to_s].type } : primary_cols[a_pk].type) &&
219
230
  (same_type = (pk_type == fk_type))
220
231
  )
221
232
  )
@@ -226,7 +237,7 @@ module Brick
226
237
  # )
227
238
  if same_type == false # We really do want to test specifically for false here, and not nil!
228
239
  puts "WARNING:
229
- Foreign key column #{a.klass.table_name}.#{a.foreign_key} is #{fk_type}, but the primary key it relates to, #{a.active_record.table_name}.#{a.active_record.primary_key}, is #{pk_type}.
240
+ Foreign key column #{a.klass.table_name}.#{a.foreign_key} is #{fk_type}, but the primary key it relates to, #{primary_klass.table_name}.#{a_pk}, is #{pk_type}.
230
241
  These columns should both be of the same type."
231
242
  end
232
243
  next
@@ -280,7 +291,7 @@ module Brick
280
291
  is_invalid_source = true
281
292
  end
282
293
  if is_invalid_source
283
- puts "WARNING: HMT relationship :#{a.name} in model #{model.name} has invalid source :#{a.source_reflection_name}."
294
+ puts " due to invalid source #{a.source_reflection_name.inspect}."
284
295
  next
285
296
  end
286
297
  else
@@ -323,6 +334,12 @@ module Brick
323
334
  true
324
335
  end
325
336
 
337
+ # Add a swagger endpoint in the same kind of way that RSwag UI does
338
+ def swagger_endpoint(url, name)
339
+ @swagger_endpoints ||= []
340
+ @swagger_endpoints << { url: url, name: name }
341
+ end
342
+
326
343
  def is_geography?(val)
327
344
  val.length < 31 && (val.length - 6) % 8 == 0 && val[0..5].bytes == [230, 16, 0, 0, 1, 12]
328
345
  end
@@ -1132,39 +1149,49 @@ In config/initializers/brick.rb appropriate entries would look something like:
1132
1149
  get("/#{controller_prefix}brick_crosstab/data", to: 'brick_gem#crosstab_data')
1133
1150
  end
1134
1151
 
1135
- if Object.const_defined?('Rswag::Ui')
1136
- rswag_path = routeset_to_use.routes.find { |r| r.app.app == Rswag::Ui::Engine }&.instance_variable_get(:@path_formatter)&.instance_variable_get(:@parts)&.join
1137
- first_endpoint_parts = nil
1138
- (doc_endpoints = Rswag::Ui.config.config_object[:urls])&.each do |doc_endpoint|
1152
+ if ((rswag_ui_present = Object.const_defined?('Rswag::Ui')) &&
1153
+ (rswag_path = routeset_to_use.routes.find { |r| r.app.app == ::Rswag::Ui::Engine }
1154
+ &.instance_variable_get(:@path_formatter)
1155
+ &.instance_variable_get(:@parts)&.join) &&
1156
+ (doc_endpoints = ::Rswag::Ui.config.config_object[:urls])) ||
1157
+ (doc_endpoints = ::Brick.instance_variable_get(:@swagger_endpoints))
1158
+ last_endpoint_parts = nil
1159
+ doc_endpoints.each do |doc_endpoint|
1139
1160
  puts "Mounting OpenApi 3.0 documentation endpoint for \"#{doc_endpoint[:name]}\" on #{doc_endpoint[:url]}" unless ::Brick.routes_done
1140
1161
  send(:get, doc_endpoint[:url], { to: 'brick_openapi#index' })
1141
1162
  endpoint_parts = doc_endpoint[:url]&.split('/')
1142
- first_endpoint_parts ||= endpoint_parts
1163
+ last_endpoint_parts = endpoint_parts
1143
1164
  end
1144
1165
  end
1145
1166
  return if ::Brick.routes_done
1146
1167
 
1147
- if Object.const_defined?('Rswag::Ui')
1148
- if doc_endpoints.present?
1149
- if rswag_path && first_endpoint_parts
1150
- puts "API documentation now available when navigating to: /#{first_endpoint_parts&.find(&:present?)}/index.html"
1168
+ if doc_endpoints.present?
1169
+ if rswag_ui_present
1170
+ if rswag_path
1171
+ puts "API documentation now available when navigating to: /#{last_endpoint_parts&.find(&:present?)}/index.html"
1151
1172
  else
1152
1173
  puts "In order to make documentation available you can put this into your routes.rb:"
1153
- puts " mount Rswag::Ui::Engine => '/#{first_endpoint_parts&.find(&:present?) || 'api-docs'}'"
1174
+ puts " mount Rswag::Ui::Engine => '/#{last_endpoint_parts&.find(&:present?) || 'api-docs'}'"
1154
1175
  end
1155
1176
  else
1156
- sample_path = rswag_path || '/api-docs'
1177
+ puts "Having this exposed, one easy way to leverage this to create HTML-based API documentation is to use Scalar.
1178
+ It will jump to life when you put these two lines into a view template or other HTML resource:
1179
+ <script id=\"api-reference\" data-url=\"#{last_endpoint_parts.join('/')}\"></script>
1180
+ <script src=\"https://cdn.jsdelivr.net/@scalar/api-reference\"></script>
1181
+ Alternatively you can add the rswag-ui gem."
1182
+ end
1183
+ elsif rswag_ui_present
1184
+ sample_path = rswag_path || '/api-docs'
1185
+ puts
1186
+ puts "Brick: rswag-ui gem detected -- to make OpenAPI 3.0 documentation available from a path such as '#{sample_path}/v1/swagger.json',"
1187
+ puts ' put code such as this in an initializer:'
1188
+ puts ' Rswag::Ui.configure do |config|'
1189
+ puts " config.swagger_endpoint '#{sample_path}/v1/swagger.json', 'API V1 Docs'"
1190
+ puts ' end'
1191
+ unless rswag_path
1157
1192
  puts
1158
- puts "Brick: rswag-ui gem detected -- to make OpenAPI 3.0 documentation available from a path such as '#{sample_path}/v1/swagger.json',"
1159
- puts ' put code such as this in an initializer:'
1160
- puts ' Rswag::Ui.configure do |config|'
1161
- puts " config.swagger_endpoint '#{sample_path}/v1/swagger.json', 'API V1 Docs'"
1162
- puts ' end'
1163
- unless rswag_path
1164
- puts
1165
- puts ' and put this into your routes.rb:'
1166
- puts " mount Rswag::Ui::Engine => '/api-docs'"
1167
- end
1193
+ puts ' and put this into your routes.rb:'
1194
+ puts " mount Rswag::Ui::Engine => '/api-docs'"
1168
1195
  end
1169
1196
  end
1170
1197
 
@@ -1777,7 +1804,7 @@ end
1777
1804
 
1778
1805
  # By default the awesome_nested_set gem from CollectiveIdea does not prefix the ORDER BY column with its table name.
1779
1806
  # You can see this snag in action in the popular Spree project -- check out the Taxonomy model. Here is a fix:
1780
- if Gem::Specification.all_names.find { |g| g.start_with?('awesome_nested_set-') }
1807
+ if Gem::Dependency.new('awesome_nested_set').matching_specs.present?
1781
1808
  require 'awesome_nested_set/columns'
1782
1809
  ::CollectiveIdea::Acts::NestedSet::Columns.class_exec do
1783
1810
  alias _brick_order_column_name order_column_name
@@ -1920,7 +1947,7 @@ module ActiveRecord
1920
1947
  # %%% Pretty much have to flat-out replace this guy (I think anyway)
1921
1948
  # Good with Rails 5.2.4 through 7.1 on this
1922
1949
  # Ransack gem includes Polyamorous which replaces #build in a different way (which we handle below)
1923
- unless Gem::Specification.all_names.any? { |g| g.start_with?('ransack-') }
1950
+ if Gem::Dependency.new('ransack').matching_specs.empty?
1924
1951
  def build(associations, base_klass, root = nil, path = '')
1925
1952
  root ||= associations
1926
1953
  associations.map do |name, right|
@@ -1976,7 +2003,7 @@ module ActiveRecord
1976
2003
  end
1977
2004
 
1978
2005
  # Now the Ransack Polyamorous version of #build
1979
- if Gem::Specification.all_names.any? { |g| g.start_with?('ransack-') }
2006
+ if Gem::Dependency.new('ransack').matching_specs.present?
1980
2007
  require "polyamorous/activerecord_#{::ActiveRecord::VERSION::STRING[0, 3]}_ruby_2/join_dependency"
1981
2008
  module Polyamorous::JoinDependencyExtensions
1982
2009
  def build(associations, base_klass, root = nil, path = '')
@@ -190,6 +190,10 @@ if ActiveRecord::Base.respond_to?(:brick_select) && !::Brick.initializer_loaded
190
190
  # config.swagger_endpoint '/api-docs/v1/swagger.json', 'API V1 Docs'
191
191
  # end
192
192
 
193
+ # # To establish OpenAPI 3.0 documentation endpoints without use of Rswag, such as if you want to use fancier
194
+ # # tooling such as Scalar API or similar, the Brick also allows you to establish endpoints directly:
195
+ # ::Brick.swagger_endpoint '/api-docs/v1/swagger.json', 'API V1 Docs'
196
+
193
197
  # # By default models are auto-created for database views, and set to be read-only. This can be skipped.
194
198
  # Brick.skip_database_views = true
195
199
 
@@ -1,7 +1,5 @@
1
1
  module Brick
2
2
  module MigrationBuilder
3
- include FancyGets
4
-
5
3
  # Many SQL types are the same as their migration data type name:
6
4
  # text, integer, bigint, date, boolean, decimal, float
7
5
  # These however are not:
@@ -48,6 +46,7 @@ module Brick
48
46
  # (Still need to find what "inet" and "json" data types map to.)
49
47
 
50
48
  class << self
49
+ include FancyGets
51
50
  def check_folder(is_insert_versions = true, is_delete_versions = false)
52
51
  versions_to_delete_or_append = nil
53
52
  if Dir.exist?(mig_path = ActiveRecord::Migrator.migrations_paths.first || "#{::Rails.root}/db/migrate")
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.185
4
+ version: 1.0.187
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lorin Thwaits
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-10-25 00:00:00.000000000 Z
11
+ date: 2023-11-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord