brick 1.0.158 → 1.0.161

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