brick 1.0.158 → 1.0.161

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: 326ec09b1c28cf7c54e54bae9ea6ceed7d7e476a177be0a41af14e04f7cc3d11
4
- data.tar.gz: 0507c22a2acf86c58737ecfedeb1a1f5ed6979b5263b28c6d6e77b0e9500ab7c
3
+ metadata.gz: b6fde6ef1ff8f9e3d6787b53c64a881a88c448ce3adfc9ca5e6a25e8f815cc30
4
+ data.tar.gz: 2bcc9fe939bc4d879168032ff16aba60ceeb08854083b4f5912649b2eb056962
5
5
  SHA512:
6
- metadata.gz: d6803593a5c3e17ef40005c405017ed4e7519024ca172a077ad377c201a7b2e2caf2a8b4bc5a0ef63f091124a44199ffd3b386db7d6b5d51352f2e3327537d81
7
- data.tar.gz: 486b0a15422b0d3150b575c8d19c24cc3434e3fd8f35335d2e490e1e69e423995a2032de913def73b4f4df0e2789c6f4af7d61930db5cc144d0a0cb76be3ebdc
6
+ metadata.gz: 8ebc0d8bc6765040e3df2a4b9debcec5d4326efd69d41e62188146c29f25bd254d381db651b4687fd6afe77d2f7ef5b6f640edde87fd7ddbd0c9b851bbabe74c
7
+ data.tar.gz: 97e7320e75a6f9589a8a96e751ad9c082826a4ae7698dcad2e487323075977f13bf2e2f8e2d889bf42d761f5649926b22d0e07e3e395456f9d04adc23fde064c
@@ -97,11 +97,13 @@ if Object.const_defined?('ActionPack') && !ActionPack.respond_to?(:version)
97
97
  end
98
98
  end
99
99
  end
100
- require 'action_view' # Needed for Rails <= 4.0
101
- if Object.const_defined?('ActionView') && !ActionView.respond_to?(:version)
102
- module ActionView
103
- def self.version
104
- ActionPack.version
100
+ if Bundler.locked_gems&.dependencies.key?('action_view')
101
+ require 'action_view' # Needed for Rails <= 4.0
102
+ if Object.const_defined?('ActionView') && !ActionView.respond_to?(:version)
103
+ module ActionView
104
+ def self.version
105
+ ActionPack.version
106
+ end
105
107
  end
106
108
  end
107
109
  end
@@ -30,14 +30,14 @@
30
30
 
31
31
  # Drag something like HierModel#name onto the rows and have it automatically add five columns -- where type=zone / where type = section / etc
32
32
 
33
- # Support for Postgres / MySQL enums (add enum to model, use model enums to make a drop-down in the UI)
34
-
35
- # Currently quadrupling up routes
36
-
37
33
  # Modal pop-up things for editing large text / date ranges / hierarchies of data
38
34
 
39
35
  # For recognised self-references, have the show page display all related objects up to the parent (or the start of a circular reference)
40
36
 
37
+ # When creating or updating an object through an auto-generated controller, it always goes to an auto-generated view template even if the user has supplied their own index.html.erb (or similar) view template
38
+
39
+ # Upon creation of a new object, when going to the index page, highlight this new object and scroll it into view (likely to the very bottom of everything, although might be sorted differently)
40
+
41
41
  # ==========================================================
42
42
  # Dynamically create model or controller classes when needed
43
43
  # ==========================================================
@@ -972,9 +972,14 @@ JOIN (SELECT #{hm_selects.map { |s| _br_quoted_name("#{'br_t0.' if from_clause}#
972
972
  (!a.options[:polymorphic] && a.klass == klass && klass_cols.include?(a.foreign_key))
973
973
  )
974
974
  end
975
+
975
976
  # ActiveStorage compatibility
976
977
  selects << 'service_name' if klass.name == 'ActiveStorage::Blob' && ActiveStorage::Blob.columns_hash.key?('service_name')
977
978
  selects << 'blob_id' if klass.name == 'ActiveStorage::Attachment' && ActiveStorage::Attachment.columns_hash.key?('blob_id')
979
+ # Pay gem compatibility
980
+ selects << 'processor' if klass.name == 'Pay::Customer' && Pay::Customer.columns_hash.key?('processor')
981
+ selects << 'customer_id' if klass.name == 'Pay::Subscription' && Pay::Subscription.columns_hash.key?('customer_id')
982
+
978
983
  pieces, my_dsl = klass.brick_parse_dsl(join_array = ::Brick::JoinArray.new, [], translations = {}, false, nil, true)
979
984
  brick_select(
980
985
  selects, where_values_hash, nil, translations: translations, join_array: join_array,
@@ -1131,6 +1136,20 @@ if Object.const_defined?('ActionView')
1131
1136
  end
1132
1137
  end
1133
1138
  end
1139
+
1140
+ module ActionDispatch::Routing
1141
+ class Mapper
1142
+ module Base
1143
+ # Pro-actively assess Brick routes. Useful when there is a "catch all" wildcard route
1144
+ # at the end of an existing `routes.rb` file, which would normally steal the show and
1145
+ # not let Brick have any fun. So just call this right before any wildcard routes, and
1146
+ # you'll be in business!
1147
+ def mount_brick_routes
1148
+ add_brick_routes unless ::Brick.routes_done
1149
+ end
1150
+ end
1151
+ end
1152
+ end
1134
1153
  end
1135
1154
 
1136
1155
  if ActiveSupport::Dependencies.respond_to?(:autoload_module!) # %%% Only works with previous non-zeitwerk auto-loading
@@ -1807,7 +1826,7 @@ class Object
1807
1826
  cspd.select! { |val| val == "'self'" }
1808
1827
  cspd << style_value
1809
1828
  else
1810
- cspd << "'sha256-QHKxqKcUq7AER1QwEu5uQXRQwC8j4iTWkE8mpOmP7ms='"
1829
+ cspd << "'sha256-VbHigzrnU2KiWIjHStrKhnGxWRv25WXQNdKr5qhevD8='"
1811
1830
  end
1812
1831
  cspd << 'https://cdn.jsdelivr.net'
1813
1832
  end
@@ -2199,7 +2218,8 @@ class Object
2199
2218
  render json: { result: ::Brick.unexclude_column(table_name, col) }
2200
2219
  else
2201
2220
  @_lookup_context.instance_variable_set("@#{singular_table_name}".to_sym,
2202
- model.send(:create, send(params_name_sym)))
2221
+ (created_obj = model.send(:create, send(params_name_sym))))
2222
+ # %%% Surface any errors to the user in a flash message
2203
2223
  @_lookup_context.instance_variable_set(:@_brick_model, model)
2204
2224
  index
2205
2225
  render :index
@@ -1667,89 +1667,9 @@ end
1667
1667
  end
1668
1668
  %>
1669
1669
  <br><br>
1670
- <%= form_for(obj.becomes(#{model_name}), options) do |f| %>
1671
- <table class=\"shadow\">
1672
- <% has_fields = false
1673
- # If it's a new record, set any default polymorphic types
1674
- bts.each do |_k, v|
1675
- if v[2]
1676
- @#{obj_name}.send(\"#\{model.brick_foreign_type(v.first)}=\", v[1].first&.first&.name)
1677
- end
1678
- end if @#{obj_name}.new_record?
1679
- rtans = #{model_name}.rich_text_association_names if #{model_name}.respond_to?(:rich_text_association_names)
1680
- (#{model_name}.column_names + (rtans || [])).each do |k|
1681
- next if (#{(pk.map(&:to_s) || []).inspect}.include?(k) && !bts.key?(k)) ||
1682
- ::Brick.config.metadata_columns.include?(k)
1683
-
1684
- col = #{model_name}.columns_hash[k]
1685
- if !col && rtans&.include?(k)
1686
- k = k[10..-1] if k.start_with?('rich_text_')
1687
- col = (rt_col ||= ActiveRecord::ConnectionAdapters::Column.new(
1688
- '', nil, ActiveRecord::ConnectionAdapters::SqlTypeMetadata.new(sql_type: 'varchar', type: :text)
1689
- )
1690
- )
1691
- end
1692
- val = @#{obj_name}.attributes[k] %>
1693
- <tr>
1694
- <th class=\"show-field\"<%= \" title=\\\"#\{col&.comment}\\\"\".html_safe if col&.respond_to?(:comment) && !col&.comment.blank? %>>
1695
- <% has_fields = true
1696
- if (bt = bts[k])
1697
- # Add a final member in this array with descriptive options to be used in <select> drop-downs
1698
- bt_name = bt[1].map { |x| x.first.name }.join('/')
1699
- # %%% Only do this if the user has permissions to edit this bt field
1700
- if bt[2] # Polymorphic?
1701
- poly_class_name = orig_poly_name = @#{obj_name}.send(model.brick_foreign_type(bt.first))
1702
- bt_pair = nil
1703
- loop do
1704
- bt_pair = bt[1].find { |pair| pair.first.name == poly_class_name }
1705
- # Accommodate any valid STI by going up the chain of inheritance
1706
- break unless bt_pair.nil? && poly_class_name = ::Brick.existing_stis[poly_class_name]
1707
- end
1708
- puts \"*** Might be missing an STI class called #\{orig_poly_name\} whose base class should have this:
1709
- *** has_many :#{table_name}, as: :#\{bt.first\}
1710
- *** Can probably auto-configure everything using these lines in an initialiser:
1711
- *** Brick.sti_namespace_prefixes = { '::#\{orig_poly_name\}' => 'SomeParentModel' }
1712
- *** Brick.polymorphics = { '#{table_name}.#\{bt.first\}' => ['SomeParentModel'] }\" if bt_pair.nil?
1713
- # descrips = @_brick_bt_descrip[bt.first][bt_class]
1714
- poly_id = @#{obj_name}.send(\"#\{bt.first\}_id\")
1715
- # bt_class.order(obj_pk = bt_class.primary_key).each { |obj| option_detail << [obj.brick_descrip(nil, obj_pk), obj.send(obj_pk)] }
1716
- end
1717
- bt_pair ||= bt[1].first # If there's no polymorphism (or polymorphism status is unknown), just get the first one
1718
- bt_class = bt_pair&.first
1719
- if bt.length < 4
1720
- bt << (option_detail = [[\"(No #\{bt_name\} chosen)\", '^^^brick_NULL^^^']])
1721
- # %%% Accommodate composite keys for obj.pk at the end here
1722
- collection, descrip_cols = bt_class&.order(Arel.sql(\"#\{bt_class.table_name}.#\{obj_pk = bt_class.primary_key}\"))&.brick_list
1723
- collection&.brick_(:each) do |obj|
1724
- option_detail << [
1725
- obj.brick_descrip(
1726
- descrip_cols&.first&.map { |col2| obj.send(col2.last) },
1727
- obj_pk
1728
- ), obj.send(obj_pk)
1729
- ]
1730
- end
1731
- end %>
1732
- BT <%= bt_class&.bt_link(bt.first) || orig_poly_name %>
1733
- <% else %>
1734
- <%= #{model_name}.human_attribute_name(k, { default: k }) %>
1735
- <% end %>
1736
- </th>
1737
- <td>
1738
- <%= f.brick_field(k, html_options = {}, val, col, bt, bt_class, bt_name, bt_pair) %>
1739
- </td>
1740
- </tr>
1741
- <% end
1742
- if has_fields %>
1743
- <tr><td colspan=\"2\"><%= f.submit({ class: 'update' }) %></td></tr>
1744
- <% else %>
1745
- <tr><td colspan=\"2\">(No displayable fields)</td></tr>
1746
- <% end %>
1747
- </table>#{
1748
- "<%= begin
1749
- ::Brick::Rails.display_binary(obj&.blob&.download, 500_000)&.html_safe
1750
- rescue
1751
- end %>" if model_name == 'ActiveStorage::Attachment'}
1752
- <% end %>
1670
+
1671
+ <%= # Write out the mega-form
1672
+ brick_form_for(obj, options, #{model_name}, bts, #{pk.inspect}) %>
1753
1673
 
1754
1674
  #{unless args.first == 'new'
1755
1675
  # Was: confirm_are_you_sure = ActionView.version < ::Gem::Version.new('7.0') ? "data: { confirm: 'Delete #\{model_name} -- Are you sure?' }" : "form: { data: { turbo_confirm: 'Delete #\{model_name} -- Are you sure?' } }"
@@ -2064,6 +1984,10 @@ document.querySelectorAll(\"input, select\").forEach(function (inp) {
2064
1984
  # In order to defer auto-creation of any routes that already exist, calculate Brick routes only after having loaded all others
2065
1985
  prepend ::Brick::RouteSet
2066
1986
  end
1987
+ ActionDispatch::Routing::Mapper.class_exec do
1988
+ include ::Brick::RouteMapper
1989
+ end
1990
+
2067
1991
  # Do the root route before the Rails Welcome one would otherwise take precedence
2068
1992
  if (route = ::Brick.config.default_route_fallback).present?
2069
1993
  action = "#{route}#{'#index' unless route.index('#')}"
@@ -67,9 +67,14 @@ module Brick::Rails::FormBuilder
67
67
  when :boolean
68
68
  out << self.check_box(method.to_sym)
69
69
  when :integer, :decimal, :float
70
- digit_pattern = col_type == :integer ? '\d*' : '\d*(?:\.\d*|)'
71
- # Used to do this for float / decimal: self.number_field method.to_sym
72
- out << self.text_field(method.to_sym, { pattern: digit_pattern, class: 'check-validity' })
70
+ if model.respond_to?(:attribute_types) && (enum_type = model.attribute_types[method]).is_a?(ActiveRecord::Enum::EnumType)
71
+ opts = enum_type.send(:mapping)&.each_with_object([]) { |v, s| s << [v.first, v.first] } || []
72
+ out << self.select(method.to_sym, [["(No #{method} chosen)", '^^^brick_NULL^^^']] + opts, { value: val || '^^^brick_NULL^^^' }, options)
73
+ else
74
+ digit_pattern = col_type == :integer ? '\d*' : '\d*(?:\.\d*|)'
75
+ # Used to do this for float / decimal: self.number_field method.to_sym
76
+ out << self.text_field(method.to_sym, { pattern: digit_pattern, class: 'check-validity' })
77
+ end
73
78
  when *DT_PICKERS.keys
74
79
  template.instance_variable_set(:@_date_fields_present, true)
75
80
  out << self.text_field(method.to_sym, { class: DT_PICKERS[col_type] })
@@ -203,6 +203,101 @@ module Brick::Rails::FormTags
203
203
  out.html_safe
204
204
  end # brick_grid
205
205
 
206
+ # Our mega show/new/update form
207
+ def brick_form_for(obj, options = {}, model = obj.class, bts = {}, pk = (obj.class.primary_key || []))
208
+ pk = [pk] unless pk.is_a?(Array)
209
+ pk.map!(&:to_s)
210
+ form_for(obj.becomes(model), options) do |f|
211
+ out = +'<table class="shadow">'
212
+ has_fields = false
213
+ # If it's a new record, set any default polymorphic types
214
+ bts&.each do |_k, v|
215
+ if v[2]
216
+ obj.send("#{model.brick_foreign_type(v.first)}=", v[1].first&.first&.name)
217
+ end
218
+ end if obj.new_record?
219
+ rtans = model.rich_text_association_names if model.respond_to?(:rich_text_association_names)
220
+ (model.column_names + (rtans || [])).each do |k|
221
+ next if (pk.include?(k) && !bts.key?(k)) ||
222
+ ::Brick.config.metadata_columns.include?(k)
223
+
224
+ col = model.columns_hash[k]
225
+ if !col && rtans&.include?(k)
226
+ k = k[10..-1] if k.start_with?('rich_text_')
227
+ col = (rt_col ||= ActiveRecord::ConnectionAdapters::Column.new(
228
+ '', nil, ActiveRecord::ConnectionAdapters::SqlTypeMetadata.new(sql_type: 'varchar', type: :text)
229
+ )
230
+ )
231
+ end
232
+ val = obj.attributes[k]
233
+ out << "
234
+ <tr>
235
+ <th class=\"show-field\"#{" title=\"#{col&.comment}\"".html_safe if col&.respond_to?(:comment) && !col&.comment.blank?}>"
236
+ has_fields = true
237
+ if (bt = bts[k])
238
+ # Add a final member in this array with descriptive options to be used in <select> drop-downs
239
+ bt_name = bt[1].map { |x| x.first.name }.join('/')
240
+ # %%% Only do this if the user has permissions to edit this bt field
241
+ if bt[2] # Polymorphic?
242
+ poly_class_name = orig_poly_name = obj.send(model.brick_foreign_type(bt.first))
243
+ bt_pair = nil
244
+ loop do
245
+ bt_pair = bt[1].find { |pair| pair.first.name == poly_class_name }
246
+ # Accommodate any valid STI by going up the chain of inheritance
247
+ break unless bt_pair.nil? && poly_class_name = ::Brick.existing_stis[poly_class_name]
248
+ end
249
+ table_name = model.name.split('::').last.underscore.pluralize
250
+ puts "*** Might be missing an STI class called #{orig_poly_name} whose base class should have this:
251
+ *** has_many :#{table_name}, as: :#{bt.first}
252
+ *** Can probably auto-configure everything using these lines in an initialiser:
253
+ *** Brick.sti_namespace_prefixes = { '::#{orig_poly_name}' => 'SomeParentModel' }
254
+ *** Brick.polymorphics = { '#{table_name}.#{bt.first}' => ['SomeParentModel'] }" if bt_pair.nil?
255
+ # descrips = @_brick_bt_descrip[bt.first][bt_class]
256
+ poly_id = obj.send("#{bt.first}_id")
257
+ # bt_class.order(obj_pk = bt_class.primary_key).each { |obj| option_detail << [obj.brick_descrip(nil, obj_pk), obj.send(obj_pk)] }
258
+ end
259
+ bt_pair ||= bt[1].first # If there's no polymorphism (or polymorphism status is unknown), just get the first one
260
+ bt_class = bt_pair&.first
261
+ if bt.length < 4
262
+ bt << (option_detail = [["(No #{bt_name} chosen)", '^^^brick_NULL^^^']])
263
+ # %%% Accommodate composite keys for obj.pk at the end here
264
+ collection, descrip_cols = bt_class&.order(Arel.sql("#{bt_class.table_name}.#{obj_pk = bt_class.primary_key}"))&.brick_list
265
+ collection&.brick_(:each) do |obj|
266
+ option_detail << [
267
+ obj.brick_descrip(
268
+ descrip_cols&.first&.map { |col2| obj.send(col2.last) },
269
+ obj_pk
270
+ ), obj.send(obj_pk)
271
+ ]
272
+ end
273
+ end
274
+ out << "BT #{bt_class&.bt_link(bt.first) || orig_poly_name}"
275
+ else
276
+ out << model.human_attribute_name(k, { default: k })
277
+ end
278
+ out << "
279
+ </th>
280
+ <td>
281
+ #{f.brick_field(k, html_options = {}, val, col, bt, bt_class, bt_name, bt_pair)}
282
+ </td>
283
+ </tr>"
284
+ end
285
+ if has_fields
286
+ out << "<tr><td colspan=\"2\">#{f.submit({ class: 'update' })}</td></tr>"
287
+ else
288
+ out << '<tr><td colspan="2">(No displayable fields)</td></tr>'
289
+ end
290
+ out << '</table>'
291
+ if model.name == 'ActiveStorage::Attachment'
292
+ begin
293
+ out << ::Brick::Rails.display_binary(obj&.blob&.download, 500_000)&.html_safe
294
+ rescue
295
+ end
296
+ end
297
+ out.html_safe
298
+ end
299
+ end # brick_form_for
300
+
206
301
  def link_to_brick(*args, **kwargs)
207
302
  return unless ::Brick.config.mode == :on
208
303
 
@@ -291,7 +386,11 @@ module Brick::Rails::FormTags
291
386
  if (links = _brick_resource_from_iv(true)).length == 1 # If there's only one match then use any text that was supplied
292
387
  link_to_brick(text || links.first.last.join('/'), links.first.first, **kwargs)
293
388
  else
294
- links.each_with_object([]) { |v, s| s << link if link = link_to_brick(v.join('/'), v, **kwargs) }.join(' &nbsp; ').html_safe
389
+ links.each_with_object([]) do |v, s|
390
+ if (link = link_to_brick(v.join('/'), v, **kwargs))
391
+ s << link
392
+ end
393
+ end.join(' &nbsp; ').html_safe
295
394
  end
296
395
  end
297
396
  end # link_to_brick
@@ -5,7 +5,7 @@ module Brick
5
5
  module VERSION
6
6
  MAJOR = 1
7
7
  MINOR = 0
8
- TINY = 158
8
+ TINY = 161
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
@@ -794,296 +794,303 @@ In config/initializers/brick.rb appropriate entries would look something like:
794
794
 
795
795
  module RouteSet
796
796
  def finalize!
797
- routeset_to_use = ::Rails.application.routes
798
- return super if self != routeset_to_use || ::Brick.routes_done
797
+ return super if self != ::Rails.application.routes || ::Brick.routes_done
799
798
 
799
+ append do
800
+ add_brick_routes
801
+ end
802
+ super
803
+ end
804
+ end
805
+
806
+ module RouteMapper
807
+ def add_brick_routes
808
+ routeset_to_use = ::Rails.application.routes
800
809
  path_prefix = ::Brick.config.path_prefix
801
- existing_controllers = routes.each_with_object({}) do |r, s|
810
+ existing_controllers = routeset_to_use.routes.each_with_object({}) do |r, s|
802
811
  c = r.defaults[:controller]
803
812
  s[c] = nil if c
804
813
  end
805
- append do
806
- tables = []
807
- views = []
808
- table_class_length = 38 # Length of "Classes that can be built from tables:"
809
- view_class_length = 37 # Length of "Classes that can be built from views:"
810
-
811
- brick_namespace_create = lambda do |path_names, res_name, options|
812
- if path_names&.present?
813
- if (path_name = path_names.pop).is_a?(Array)
814
- module_name = path_name[1]
815
- path_name = path_name.first
816
- end
817
- send(:scope, { module: module_name || path_name, path: path_name, as: path_name }) do
818
- brick_namespace_create.call(path_names, res_name, options)
819
- end
820
- else
821
- send(:resources, res_name.to_sym, **options)
814
+
815
+ tables = []
816
+ views = []
817
+ table_class_length = 38 # Length of "Classes that can be built from tables:"
818
+ view_class_length = 37 # Length of "Classes that can be built from views:"
819
+
820
+ brick_namespace_create = lambda do |path_names, res_name, options|
821
+ if path_names&.present?
822
+ if (path_name = path_names.pop).is_a?(Array)
823
+ module_name = path_name[1]
824
+ path_name = path_name.first
822
825
  end
826
+ send(:scope, { module: module_name || path_name, path: path_name, as: path_name }) do
827
+ brick_namespace_create.call(path_names, res_name, options)
828
+ end
829
+ else
830
+ send(:resources, res_name.to_sym, **options)
823
831
  end
832
+ end
824
833
 
825
- # %%% TODO: If no auto-controllers then enumerate the controllers folder in order to build matching routes
826
- # If auto-controllers and auto-models are both enabled then this makes sense:
827
- controller_prefix = (path_prefix ? "#{path_prefix}/" : '')
828
- sti_subclasses = ::Brick.config.sti_namespace_prefixes.each_with_object(Hash.new { |h, k| h[k] = [] }) do |v, s|
829
- # Turn something like {"::Spouse"=>"Person", "::Friend"=>"Person"} into {"Person"=>["Spouse", "Friend"]}
830
- s[v.last] << v.first[2..-1] unless v.first.end_with?('::')
831
- end
832
- versioned_views = {} # Track which views have already been done for each api_root
833
- ::Brick.relations.each do |k, v|
834
- if (schema_name = v.fetch(:schema, nil))
835
- schema_prefix = "#{schema_name}."
836
- end
834
+ # %%% TODO: If no auto-controllers then enumerate the controllers folder in order to build matching routes
835
+ # If auto-controllers and auto-models are both enabled then this makes sense:
836
+ controller_prefix = (path_prefix ? "#{path_prefix}/" : '')
837
+ sti_subclasses = ::Brick.config.sti_namespace_prefixes.each_with_object(Hash.new { |h, k| h[k] = [] }) do |v, s|
838
+ # Turn something like {"::Spouse"=>"Person", "::Friend"=>"Person"} into {"Person"=>["Spouse", "Friend"]}
839
+ s[v.last] << v.first[2..-1] unless v.first.end_with?('::')
840
+ end
841
+ versioned_views = {} # Track which views have already been done for each api_root
842
+ ::Brick.relations.each do |k, v|
843
+ if (schema_name = v.fetch(:schema, nil))
844
+ schema_prefix = "#{schema_name}."
845
+ end
837
846
 
838
- next if !(resource_name = v.fetch(:resource, nil)) ||
839
- existing_controllers.key?(
840
- controller_prefix + (resource_name = "#{schema_prefix&.tr('.', '/')}#{resource_name}".pluralize)
841
- )
842
-
843
- object_name = k.split('.').last # Take off any first schema part
844
-
845
- full_schema_prefix = if (aps = v.fetch(:auto_prefixed_schema, nil))
846
- aps = aps[0..-2] if aps[-1] == '_'
847
- (schema_prefix&.dup || +'') << "#{aps}."
848
- else
849
- schema_prefix
850
- end
851
-
852
- # Track routes being built
853
- if (class_name = v.fetch(:class_name, nil))
854
- if v.key?(:isView)
855
- view_class_length = class_name.length if class_name.length > view_class_length
856
- views
857
- else
858
- table_class_length = class_name.length if class_name.length > table_class_length
859
- tables
860
- end << [class_name, aps, resource_name]
861
- end
847
+ next if !(resource_name = v.fetch(:resource, nil)) ||
848
+ existing_controllers.key?(
849
+ controller_prefix + (resource_name = "#{schema_prefix&.tr('.', '/')}#{resource_name}".pluralize)
850
+ )
862
851
 
863
- options = {}
864
- options[:only] = [:index, :show] if v.key?(:isView)
865
-
866
- # First do the normal routes
867
- prefixes = []
868
- prefixes << [aps, v[:class_name]&.split('::')[-2]&.underscore] if aps
869
- prefixes << schema_name if schema_name
870
- prefixes << path_prefix if path_prefix
871
- brick_namespace_create.call(prefixes, v[:resource], options)
872
- sti_subclasses.fetch(class_name, nil)&.each do |sc| # Add any STI subclass routes for this relation
873
- brick_namespace_create.call(prefixes, sc.underscore.tr('/', '_').pluralize, options)
874
- end
852
+ object_name = k.split('.').last # Take off any first schema part
875
853
 
876
- # Now the API routes if necessary
877
- full_resource = nil
878
- ::Brick.api_roots&.each do |api_root|
879
- api_done_views = (versioned_views[api_root] ||= {})
880
- found = nil
881
- test_ver_num = nil
882
- view_relation = nil
883
- # If it's a view then see if there's a versioned one available by searching for resource names
884
- # versioned with the closest number (equal to or less than) compared with our API version number.
885
- if v.key?(:isView)
886
- if (ver = object_name.match(/^v([\d_]*)/)&.captures&.first) && ver[-1] == '_'
887
- core_object_name = object_name[ver.length + 1..-1]
888
- next if api_done_views.key?(unversioned = "#{schema_prefix}v_#{core_object_name}")
889
-
890
- # Expect that the last item in the path generally holds versioning information
891
- api_ver = api_root.split('/')[-1]&.gsub('_', '.')
892
- vn_idx = api_ver.rindex(/[^\d._]/) # Position of the first numeric digit at the end of the version number
893
- # Was: .to_d
894
- test_ver_num = api_ver_num = api_ver[vn_idx + 1..-1].gsub('_', '.').to_i # Attempt to turn something like "v3" into the decimal value 3
895
- # puts [api_ver, vn_idx, api_ver_num, unversioned].inspect
896
-
897
- next if ver.to_i > api_ver_num # Don't surface any newer views in an older API
898
-
899
- test_ver_num -= 1 until test_ver_num.zero? ||
900
- (view_relation = ::Brick.relations.fetch(
901
- found = "#{schema_prefix}v#{test_ver_num}_#{core_object_name}", nil
902
- ))
903
- api_done_views[unversioned] = nil # Mark that for this API version this view is done
904
-
905
- # puts "Found #{found}" if view_relation
906
- # If we haven't found "v3_view_name" or "v2_view_name" or so forth, at the last
907
- # fall back to simply looking for "v_view_name", and then finally "view_name".
908
- no_v_prefix_name = "#{schema_prefix}#{core_object_name}"
909
- standard_prefix = 'v_'
910
- else
911
- core_object_name = object_name
912
- end
913
- if (rvp = ::Brick.config.api_remove_view_prefix) && core_object_name.start_with?(rvp)
914
- core_object_name.slice!(0, rvp.length)
915
- end
916
- no_prefix_name = "#{schema_prefix}#{core_object_name}"
917
- unversioned = "#{schema_prefix}#{standard_prefix}#{::Brick.config.api_add_view_prefix}#{core_object_name}"
854
+ full_schema_prefix = if (aps = v.fetch(:auto_prefixed_schema, nil))
855
+ aps = aps[0..-2] if aps[-1] == '_'
856
+ (schema_prefix&.dup || +'') << "#{aps}."
857
+ else
858
+ schema_prefix
859
+ end
860
+
861
+ # Track routes being built
862
+ if (class_name = v.fetch(:class_name, nil))
863
+ if v.key?(:isView)
864
+ view_class_length = class_name.length if class_name.length > view_class_length
865
+ views
866
+ else
867
+ table_class_length = class_name.length if class_name.length > table_class_length
868
+ tables
869
+ end << [class_name, aps, resource_name]
870
+ end
871
+
872
+ options = {}
873
+ options[:only] = [:index, :show] if v.key?(:isView)
874
+
875
+ # First do the normal routes
876
+ prefixes = []
877
+ prefixes << [aps, v[:class_name]&.split('::')[-2]&.underscore] if aps
878
+ prefixes << schema_name if schema_name
879
+ prefixes << path_prefix if path_prefix
880
+ brick_namespace_create.call(prefixes, v[:resource], options)
881
+ sti_subclasses.fetch(class_name, nil)&.each do |sc| # Add any STI subclass routes for this relation
882
+ brick_namespace_create.call(prefixes, sc.underscore.tr('/', '_').pluralize, options)
883
+ end
884
+
885
+ # Now the API routes if necessary
886
+ full_resource = nil
887
+ ::Brick.api_roots&.each do |api_root|
888
+ api_done_views = (versioned_views[api_root] ||= {})
889
+ found = nil
890
+ test_ver_num = nil
891
+ view_relation = nil
892
+ # If it's a view then see if there's a versioned one available by searching for resource names
893
+ # versioned with the closest number (equal to or less than) compared with our API version number.
894
+ if v.key?(:isView)
895
+ if (ver = object_name.match(/^v([\d_]*)/)&.captures&.first) && ver[-1] == '_'
896
+ core_object_name = object_name[ver.length + 1..-1]
897
+ next if api_done_views.key?(unversioned = "#{schema_prefix}v_#{core_object_name}")
898
+
899
+ # Expect that the last item in the path generally holds versioning information
900
+ api_ver = api_root.split('/')[-1]&.gsub('_', '.')
901
+ vn_idx = api_ver.rindex(/[^\d._]/) # Position of the first numeric digit at the end of the version number
902
+ # Was: .to_d
903
+ test_ver_num = api_ver_num = api_ver[vn_idx + 1..-1].gsub('_', '.').to_i # Attempt to turn something like "v3" into the decimal value 3
904
+ # puts [api_ver, vn_idx, api_ver_num, unversioned].inspect
905
+
906
+ next if ver.to_i > api_ver_num # Don't surface any newer views in an older API
907
+
908
+ test_ver_num -= 1 until test_ver_num.zero? ||
909
+ (view_relation = ::Brick.relations.fetch(
910
+ found = "#{schema_prefix}v#{test_ver_num}_#{core_object_name}", nil
911
+ ))
912
+ api_done_views[unversioned] = nil # Mark that for this API version this view is done
913
+
914
+ # puts "Found #{found}" if view_relation
915
+ # If we haven't found "v3_view_name" or "v2_view_name" or so forth, at the last
916
+ # fall back to simply looking for "v_view_name", and then finally "view_name".
917
+ no_v_prefix_name = "#{schema_prefix}#{core_object_name}"
918
+ standard_prefix = 'v_'
918
919
  else
919
- unversioned = k
920
+ core_object_name = object_name
921
+ end
922
+ if (rvp = ::Brick.config.api_remove_view_prefix) && core_object_name.start_with?(rvp)
923
+ core_object_name.slice!(0, rvp.length)
920
924
  end
925
+ no_prefix_name = "#{schema_prefix}#{core_object_name}"
926
+ unversioned = "#{schema_prefix}#{standard_prefix}#{::Brick.config.api_add_view_prefix}#{core_object_name}"
927
+ else
928
+ unversioned = k
929
+ end
921
930
 
922
- view_relation ||= ::Brick.relations.fetch(found = unversioned, nil) ||
923
- (no_v_prefix_name && ::Brick.relations.fetch(found = no_v_prefix_name, nil)) ||
924
- (no_prefix_name && ::Brick.relations.fetch(found = no_prefix_name, nil))
925
- if view_relation
926
- actions = view_relation.key?(:isView) ? [:index, :show] : ::Brick::ALL_API_ACTIONS # By default all actions are allowed
927
- # Call proc that limits which endpoints get surfaced based on version, table or view name, method (get list / get one / post / patch / delete)
928
- # Returning nil makes it do nothing, false makes it skip creating this endpoint, and an array of up to
929
- # these 3 things controls and changes the nature of the endpoint that gets built:
930
- # (updated api_name, name of different relation to route to, allowed actions such as :index, :show, :create, etc)
931
- proc_result = if (filter = ::Brick.config.api_filter).is_a?(Proc)
932
- begin
933
- num_args = filter.arity.negative? ? 6 : filter.arity
934
- filter.call(*[unversioned, k, view_relation, actions, api_ver_num, found, test_ver_num][0...num_args])
935
- rescue StandardError => e
936
- puts "::Brick.api_filter Proc error: #{e.message}"
937
- end
931
+ view_relation ||= ::Brick.relations.fetch(found = unversioned, nil) ||
932
+ (no_v_prefix_name && ::Brick.relations.fetch(found = no_v_prefix_name, nil)) ||
933
+ (no_prefix_name && ::Brick.relations.fetch(found = no_prefix_name, nil))
934
+ if view_relation
935
+ actions = view_relation.key?(:isView) ? [:index, :show] : ::Brick::ALL_API_ACTIONS # By default all actions are allowed
936
+ # Call proc that limits which endpoints get surfaced based on version, table or view name, method (get list / get one / post / patch / delete)
937
+ # Returning nil makes it do nothing, false makes it skip creating this endpoint, and an array of up to
938
+ # these 3 things controls and changes the nature of the endpoint that gets built:
939
+ # (updated api_name, name of different relation to route to, allowed actions such as :index, :show, :create, etc)
940
+ proc_result = if (filter = ::Brick.config.api_filter).is_a?(Proc)
941
+ begin
942
+ num_args = filter.arity.negative? ? 6 : filter.arity
943
+ filter.call(*[unversioned, k, view_relation, actions, api_ver_num, found, test_ver_num][0...num_args])
944
+ rescue StandardError => e
945
+ puts "::Brick.api_filter Proc error: #{e.message}"
938
946
  end
939
- # proc_result expects to receive back: [updated_api_name, to_other_relation, allowed_actions]
947
+ end
948
+ # proc_result expects to receive back: [updated_api_name, to_other_relation, allowed_actions]
940
949
 
941
- case proc_result
942
- when NilClass
943
- # Do nothing differently than what normal behaviour would be
944
- when FalseClass # Skip implementing this endpoint
945
- view_relation[:api][api_ver_num] = nil
946
- next
947
- when Array # Did they give back an array of actions?
948
- unless proc_result.any? { |pr| ::Brick::ALL_API_ACTIONS.exclude?(pr) }
949
- proc_result = [unversioned, to_relation, proc_result]
950
- end
951
- # Otherwise don't change this array because it's probably legit
952
- when String
953
- proc_result = [proc_result] # Treat this as the surfaced api_name (path) they want to use for this endpoint
954
- else
955
- puts "::Brick.api_filter Proc warning: Unable to parse this result returned: \n #{proc_result.inspect}"
956
- proc_result = nil # Couldn't understand what in the world was returned
950
+ case proc_result
951
+ when NilClass
952
+ # Do nothing differently than what normal behaviour would be
953
+ when FalseClass # Skip implementing this endpoint
954
+ view_relation[:api][api_ver_num] = nil
955
+ next
956
+ when Array # Did they give back an array of actions?
957
+ unless proc_result.any? { |pr| ::Brick::ALL_API_ACTIONS.exclude?(pr) }
958
+ proc_result = [unversioned, to_relation, proc_result]
957
959
  end
960
+ # Otherwise don't change this array because it's probably legit
961
+ when String
962
+ proc_result = [proc_result] # Treat this as the surfaced api_name (path) they want to use for this endpoint
963
+ else
964
+ puts "::Brick.api_filter Proc warning: Unable to parse this result returned: \n #{proc_result.inspect}"
965
+ proc_result = nil # Couldn't understand what in the world was returned
966
+ end
958
967
 
959
- if proc_result&.present?
960
- if proc_result[1] # to_other_relation
961
- if (new_view_relation = ::Brick.relations.fetch(proc_result[1], nil))
962
- k = proc_result[1] # Route this call over to this different relation
963
- view_relation = new_view_relation
964
- else
965
- puts "::Brick.api_filter Proc warning: Unable to find new suggested relation with name #{proc_result[1]} -- sticking with #{k} instead."
966
- end
967
- end
968
- if proc_result.first&.!=(k) # updated_api_name -- a different name than this relation would normally have
969
- found = proc_result.first
968
+ if proc_result&.present?
969
+ if proc_result[1] # to_other_relation
970
+ if (new_view_relation = ::Brick.relations.fetch(proc_result[1], nil))
971
+ k = proc_result[1] # Route this call over to this different relation
972
+ view_relation = new_view_relation
973
+ else
974
+ puts "::Brick.api_filter Proc warning: Unable to find new suggested relation with name #{proc_result[1]} -- sticking with #{k} instead."
970
975
  end
971
- actions &= proc_result[2] if proc_result[2] # allowed_actions
972
976
  end
973
- (view_relation[:api][api_ver_num] ||= {})[unversioned] = actions # Add to the list of API paths this resource responds to
974
-
975
- # view_ver_num = if (first_part = k.split('_').first) =~ /^v[\d_]+/
976
- # first_part[1..-1].gsub('_', '.').to_i
977
- # end
978
- controller_name = if (last = view_relation.fetch(:resource, nil)&.pluralize)
979
- "#{full_schema_prefix}#{last}"
980
- else
981
- found
982
- end.tr('.', '/')
983
-
984
- { :index => 'get', :create => 'post' }.each do |action, method|
985
- if actions.include?(action)
986
- # Normally goes to something like: /api/v1/employees
987
- send(method, "#{api_root}#{unversioned.tr('.', '/')}", { to: "#{controller_prefix}#{controller_name}##{action}" })
988
- end
977
+ if proc_result.first&.!=(k) # updated_api_name -- a different name than this relation would normally have
978
+ found = proc_result.first
989
979
  end
990
- # %%% We do not yet surface the #show action
991
- if (id_col = view_relation[:pk]&.first) # ID-dependent stuff
992
- { :update => ['put', 'patch'], :destroy => ['delete'] }.each do |action, methods|
993
- if actions.include?(action)
994
- methods.each do |method|
995
- send(method, "#{api_root}#{unversioned.tr('.', '/')}/:#{id_col}", { to: "#{controller_prefix}#{controller_name}##{action}" })
996
- end
980
+ actions &= proc_result[2] if proc_result[2] # allowed_actions
981
+ end
982
+ (view_relation[:api][api_ver_num] ||= {})[unversioned] = actions # Add to the list of API paths this resource responds to
983
+
984
+ # view_ver_num = if (first_part = k.split('_').first) =~ /^v[\d_]+/
985
+ # first_part[1..-1].gsub('_', '.').to_i
986
+ # end
987
+ controller_name = if (last = view_relation.fetch(:resource, nil)&.pluralize)
988
+ "#{full_schema_prefix}#{last}"
989
+ else
990
+ found
991
+ end.tr('.', '/')
992
+
993
+ { :index => 'get', :create => 'post' }.each do |action, method|
994
+ if actions.include?(action)
995
+ # Normally goes to something like: /api/v1/employees
996
+ send(method, "#{api_root}#{unversioned.tr('.', '/')}", { to: "#{controller_prefix}#{controller_name}##{action}" })
997
+ end
998
+ end
999
+ # %%% We do not yet surface the #show action
1000
+ if (id_col = view_relation[:pk]&.first) # ID-dependent stuff
1001
+ { :update => ['put', 'patch'], :destroy => ['delete'] }.each do |action, methods|
1002
+ if actions.include?(action)
1003
+ methods.each do |method|
1004
+ send(method, "#{api_root}#{unversioned.tr('.', '/')}/:#{id_col}", { to: "#{controller_prefix}#{controller_name}##{action}" })
997
1005
  end
998
1006
  end
999
1007
  end
1000
1008
  end
1001
1009
  end
1010
+ end
1002
1011
 
1003
- # Trestle compatibility
1004
- if Object.const_defined?('Trestle') && ::Trestle.config.options&.key?(:site_title) &&
1005
- !Object.const_defined?("#{(res_name = resource_name.tr('/', '_')).camelize}Admin")
1006
- begin
1007
- ::Trestle.resource(res_sym = res_name.to_sym, model: class_name&.constantize) do
1008
- menu { item res_sym, icon: "fa fa-star" }
1009
- end
1010
- rescue
1012
+ # Trestle compatibility
1013
+ if Object.const_defined?('Trestle') && ::Trestle.config.options&.key?(:site_title) &&
1014
+ !Object.const_defined?("#{(res_name = resource_name.tr('/', '_')).camelize}Admin")
1015
+ begin
1016
+ ::Trestle.resource(res_sym = res_name.to_sym, model: class_name&.constantize) do
1017
+ menu { item res_sym, icon: "fa fa-star" }
1011
1018
  end
1019
+ rescue
1012
1020
  end
1013
1021
  end
1022
+ end
1014
1023
 
1015
- if (named_routes = instance_variable_get(:@set).named_routes).respond_to?(:find)
1016
- if ::Brick.config.add_status && (status_as = "#{controller_prefix.tr('/', '_')}brick_status".to_sym)
1017
- (
1018
- !(status_route = instance_variable_get(:@set).named_routes.find { |route| route.first == status_as }&.last) ||
1019
- !status_route.ast.to_s.include?("/#{controller_prefix}brick_status/")
1020
- )
1021
- get("/#{controller_prefix}brick_status", to: 'brick_gem#status', as: status_as.to_s)
1022
- end
1023
-
1024
- if ::Brick.config.add_orphans && (orphans_as = "#{controller_prefix.tr('/', '_')}brick_orphans".to_sym)
1025
- (
1026
- !(orphans_route = instance_variable_get(:@set).named_routes.find { |route| route.first == orphans_as }&.last) ||
1027
- !orphans_route.ast.to_s.include?("/#{controller_prefix}brick_orphans/")
1028
- )
1029
- get("/#{controller_prefix}brick_orphans", to: 'brick_gem#orphans', as: 'brick_orphans')
1030
- end
1024
+ if (named_routes = instance_variable_get(:@set).named_routes).respond_to?(:find)
1025
+ if ::Brick.config.add_status && (status_as = "#{controller_prefix.tr('/', '_')}brick_status".to_sym)
1026
+ (
1027
+ !(status_route = instance_variable_get(:@set).named_routes.find { |route| route.first == status_as }&.last) ||
1028
+ !status_route.ast.to_s.include?("/#{controller_prefix}brick_status/")
1029
+ )
1030
+ get("/#{controller_prefix}brick_status", to: 'brick_gem#status', as: status_as.to_s)
1031
1031
  end
1032
1032
 
1033
- if instance_variable_get(:@set).named_routes.names.exclude?(:brick_crosstab)
1034
- get("/#{controller_prefix}brick_crosstab", to: 'brick_gem#crosstab', as: 'brick_crosstab')
1035
- get("/#{controller_prefix}brick_crosstab/data", to: 'brick_gem#crosstab_data')
1033
+ if ::Brick.config.add_orphans && (orphans_as = "#{controller_prefix.tr('/', '_')}brick_orphans".to_sym)
1034
+ (
1035
+ !(orphans_route = instance_variable_get(:@set).named_routes.find { |route| route.first == orphans_as }&.last) ||
1036
+ !orphans_route.ast.to_s.include?("/#{controller_prefix}brick_orphans/")
1037
+ )
1038
+ get("/#{controller_prefix}brick_orphans", to: 'brick_gem#orphans', as: 'brick_orphans')
1036
1039
  end
1040
+ end
1037
1041
 
1038
- if Object.const_defined?('Rswag::Ui')
1039
- rswag_path = routeset_to_use.routes.find { |r| r.app.app == Rswag::Ui::Engine }&.instance_variable_get(:@path_formatter)&.instance_variable_get(:@parts)&.join
1040
- first_endpoint_parts = nil
1041
- (doc_endpoints = Rswag::Ui.config.config_object[:urls])&.each do |doc_endpoint|
1042
- puts "Mounting OpenApi 3.0 documentation endpoint for \"#{doc_endpoint[:name]}\" on #{doc_endpoint[:url]}" unless ::Brick.routes_done
1043
- send(:get, doc_endpoint[:url], { to: 'brick_openapi#index' })
1044
- endpoint_parts = doc_endpoint[:url]&.split('/')
1045
- first_endpoint_parts ||= endpoint_parts
1046
- end
1042
+ if instance_variable_get(:@set).named_routes.names.exclude?(:brick_crosstab)
1043
+ get("/#{controller_prefix}brick_crosstab", to: 'brick_gem#crosstab', as: 'brick_crosstab')
1044
+ get("/#{controller_prefix}brick_crosstab/data", to: 'brick_gem#crosstab_data')
1045
+ end
1046
+
1047
+ if Object.const_defined?('Rswag::Ui')
1048
+ rswag_path = routeset_to_use.routes.find { |r| r.app.app == Rswag::Ui::Engine }&.instance_variable_get(:@path_formatter)&.instance_variable_get(:@parts)&.join
1049
+ first_endpoint_parts = nil
1050
+ (doc_endpoints = Rswag::Ui.config.config_object[:urls])&.each do |doc_endpoint|
1051
+ puts "Mounting OpenApi 3.0 documentation endpoint for \"#{doc_endpoint[:name]}\" on #{doc_endpoint[:url]}" unless ::Brick.routes_done
1052
+ send(:get, doc_endpoint[:url], { to: 'brick_openapi#index' })
1053
+ endpoint_parts = doc_endpoint[:url]&.split('/')
1054
+ first_endpoint_parts ||= endpoint_parts
1047
1055
  end
1048
- next if ::Brick.routes_done
1056
+ end
1057
+ return if ::Brick.routes_done
1049
1058
 
1050
- if Object.const_defined?('Rswag::Ui')
1051
- if doc_endpoints.present?
1052
- if rswag_path && first_endpoint_parts
1053
- puts "API documentation now available when navigating to: /#{first_endpoint_parts&.find(&:present?)}/index.html"
1054
- else
1055
- puts "In order to make documentation available you can put this into your routes.rb:"
1056
- puts " mount Rswag::Ui::Engine => '/#{first_endpoint_parts&.find(&:present?) || 'api-docs'}'"
1057
- end
1059
+ if Object.const_defined?('Rswag::Ui')
1060
+ if doc_endpoints.present?
1061
+ if rswag_path && first_endpoint_parts
1062
+ puts "API documentation now available when navigating to: /#{first_endpoint_parts&.find(&:present?)}/index.html"
1058
1063
  else
1059
- sample_path = rswag_path || '/api-docs'
1064
+ puts "In order to make documentation available you can put this into your routes.rb:"
1065
+ puts " mount Rswag::Ui::Engine => '/#{first_endpoint_parts&.find(&:present?) || 'api-docs'}'"
1066
+ end
1067
+ else
1068
+ sample_path = rswag_path || '/api-docs'
1069
+ puts
1070
+ puts "Brick: rswag-ui gem detected -- to make OpenAPI 3.0 documentation available from a path such as '#{sample_path}/v1/swagger.json',"
1071
+ puts ' put code such as this in an initializer:'
1072
+ puts ' Rswag::Ui.configure do |config|'
1073
+ puts " config.swagger_endpoint '#{sample_path}/v1/swagger.json', 'API V1 Docs'"
1074
+ puts ' end'
1075
+ unless rswag_path
1060
1076
  puts
1061
- puts "Brick: rswag-ui gem detected -- to make OpenAPI 3.0 documentation available from a path such as '#{sample_path}/v1/swagger.json',"
1062
- puts ' put code such as this in an initializer:'
1063
- puts ' Rswag::Ui.configure do |config|'
1064
- puts " config.swagger_endpoint '#{sample_path}/v1/swagger.json', 'API V1 Docs'"
1065
- puts ' end'
1066
- unless rswag_path
1067
- puts
1068
- puts ' and put this into your routes.rb:'
1069
- puts " mount Rswag::Ui::Engine => '/api-docs'"
1070
- end
1077
+ puts ' and put this into your routes.rb:'
1078
+ puts " mount Rswag::Ui::Engine => '/api-docs'"
1071
1079
  end
1072
1080
  end
1081
+ end
1073
1082
 
1074
- puts "\n" if tables.present? || views.present?
1075
- if tables.present?
1076
- puts "Classes that can be built from tables:#{' ' * (table_class_length - 38)} Path:"
1077
- puts "======================================#{' ' * (table_class_length - 38)} ====="
1078
- ::Brick.display_classes(controller_prefix, tables, table_class_length)
1079
- end
1080
- if views.present?
1081
- puts "Classes that can be built from views:#{' ' * (view_class_length - 37)} Path:"
1082
- puts "=====================================#{' ' * (view_class_length - 37)} ====="
1083
- ::Brick.display_classes(controller_prefix, views, view_class_length)
1084
- end
1083
+ puts "\n" if tables.present? || views.present?
1084
+ if tables.present?
1085
+ puts "Classes that can be built from tables:#{' ' * (table_class_length - 38)} Path:"
1086
+ puts "======================================#{' ' * (table_class_length - 38)} ====="
1087
+ ::Brick.display_classes(controller_prefix, tables, table_class_length)
1088
+ end
1089
+ if views.present?
1090
+ puts "Classes that can be built from views:#{' ' * (view_class_length - 37)} Path:"
1091
+ puts "=====================================#{' ' * (view_class_length - 37)} ====="
1092
+ ::Brick.display_classes(controller_prefix, views, view_class_length)
1085
1093
  end
1086
- super
1087
1094
  ::Brick.routes_done = true
1088
1095
  end
1089
1096
  end
@@ -1112,20 +1119,22 @@ require 'active_record/relation'
1112
1119
  require 'active_record/relation/query_methods' if ActiveRecord.version < ::Gem::Version.new('5')
1113
1120
  require 'rails/railtie' if ActiveRecord.version < ::Gem::Version.new('4.2')
1114
1121
 
1115
- # Rake tasks
1116
- class Railtie < ::Rails::Railtie
1117
- Dir.glob("#{File.expand_path(__dir__)}/brick/tasks/**/*.rake").each { |task| load task }
1118
- end
1122
+ if Object.const_defined?('Rails')
1123
+ # Rake tasks
1124
+ class Railtie < ::Rails::Railtie
1125
+ Dir.glob("#{File.expand_path(__dir__)}/brick/tasks/**/*.rake").each { |task| load task }
1126
+ end
1119
1127
 
1120
- # Rails < 4.2 does not have env
1121
- module ::Rails
1122
- unless respond_to?(:env)
1123
- def self.env
1124
- @_env ||= ActiveSupport::StringInquirer.new(ENV["RAILS_ENV"] || ENV["RACK_ENV"] || "development")
1125
- end
1128
+ # Rails < 4.2 does not have env
1129
+ module ::Rails
1130
+ unless respond_to?(:env)
1131
+ def self.env
1132
+ @_env ||= ActiveSupport::StringInquirer.new(ENV["RAILS_ENV"] || ENV["RACK_ENV"] || "development")
1133
+ end
1126
1134
 
1127
- def self.env=(environment)
1128
- @_env = ActiveSupport::StringInquirer.new(environment)
1135
+ def self.env=(environment)
1136
+ @_env = ActiveSupport::StringInquirer.new(environment)
1137
+ end
1129
1138
  end
1130
1139
  end
1131
1140
  end
@@ -1,5 +1,7 @@
1
1
  module Brick
2
2
  module MigrationBuilder
3
+ include FancyGets
4
+
3
5
  # Many SQL types are the same as their migration data type name:
4
6
  # text, integer, bigint, date, boolean, decimal, float
5
7
  # These however are not:
@@ -8,7 +8,6 @@ require 'generators/brick/migration_builder'
8
8
  module Brick
9
9
  # Auto-generates migration files
10
10
  class MigrationsGenerator < ::Rails::Generators::Base
11
- include FancyGets
12
11
  include ::Brick::MigrationBuilder
13
12
 
14
13
  desc 'Auto-generates migration files for an existing database.'
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.158
4
+ version: 1.0.161
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-07-29 00:00:00.000000000 Z
11
+ date: 2023-08-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord