brick 1.0.185 → 1.0.187

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: 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