brick 1.0.203 → 1.0.205

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: 7653a7b2f496e0ade8937b6352b66d06a63dc47487a2472ebf5e5f5b94faf711
4
- data.tar.gz: b4723c7d202d7cdaf125bd0ca6bc52852b89c813444bf8e4662724a591d7a7bc
3
+ metadata.gz: 3abdf25aeb401676febcc1ea98ce104a9e005ecae652f17daf3736baab63d5ea
4
+ data.tar.gz: 195eb8e27607f719808954914a409b356c249384cacd0535fab65652b02cd4ec
5
5
  SHA512:
6
- metadata.gz: c29614452bbbd5b1c52e6fcee20fd2308479e508a03d15d98ddd3ca73c3ad746dff9e9bfffb8979768f456d68ce5bbfaa286d96c2ef62c65e306bd3d0fa15495
7
- data.tar.gz: f8a2ac34c8a34a3a7308a49b6e17a57bf71c13718a58838f61e8e5d45699f3d9dee766a3786d4fd11be52601f02e9168803f49a8b4ce35ef7d404bef95523584
6
+ metadata.gz: 187b1740a3f0e54f061c9b293df233c32993eb00ca4a218e1b32b7888c8b72c4fb9d2889ec7a2a469f95d3b39242b9adc8c02167c76065a5dcfd45262714793c
7
+ data.tar.gz: 132fecbea3bcf8783a0ad2ca540747af4a74e882d0fdba60bf0491c0ee19e52e9ef378d6a39ab3df89cbac3bcd6dee760959f969f45e17587b6a0b643f9e1bb3
data/lib/brick/config.rb CHANGED
@@ -234,7 +234,7 @@ module Brick
234
234
 
235
235
  # Polymorphic associations
236
236
  def polymorphics
237
- @mutex.synchronize { @polymorphics }
237
+ @mutex.synchronize { @polymorphics ||= {} }
238
238
  end
239
239
 
240
240
  def polymorphics=(polys)
@@ -344,7 +344,7 @@ module Brick
344
344
  end
345
345
 
346
346
  def table_name_prefixes
347
- @mutex.synchronize { @table_name_prefixes }
347
+ @mutex.synchronize { @table_name_prefixes ||= {} }
348
348
  end
349
349
 
350
350
  def table_name_prefixes=(value)
@@ -384,7 +384,7 @@ module Brick
384
384
  end
385
385
 
386
386
  def metadata_columns
387
- @mutex.synchronize { @metadata_columns }
387
+ @mutex.synchronize { @metadata_columns ||= ['created_at', 'updated_at', 'deleted_at'] }
388
388
  end
389
389
 
390
390
  def metadata_columns=(columns)
@@ -126,10 +126,11 @@ module ActiveRecord
126
126
  return @_brick_primary_key if instance_variable_defined?(:@_brick_primary_key)
127
127
 
128
128
  pk = begin
129
- primary_key.is_a?(String) ? [primary_key] : primary_key.dup || []
130
- rescue
131
- []
132
- end
129
+ primary_key
130
+ rescue
131
+ superclass.respond_to?(:primary_key) && superclass.primary_key
132
+ end
133
+ pk = pk.is_a?(String) ? [pk] : pk.dup || []
133
134
  pk.map! { |pk_part| pk_part =~ /^[A-Z0-9_]+$/ ? pk_part.downcase : pk_part } unless connection.adapter_name == 'MySQL2'
134
135
  # Just return [] if we're missing any part of the primary key. (PK is usually just "id")
135
136
  if relation && pk.present?
@@ -1174,34 +1175,6 @@ Might want to add this in your brick.rb:
1174
1175
  end
1175
1176
  end
1176
1177
 
1177
- if ::Brick.enable_routes? && Object.const_defined?('ActionDispatch')
1178
- require 'brick/route_mapper'
1179
- ActionDispatch::Routing::RouteSet.class_exec do
1180
- # In order to defer auto-creation of any routes that already exist, calculate Brick routes only after having loaded all others
1181
- prepend ::Brick::RouteSet
1182
- end
1183
- ActionDispatch::Routing::Mapper.class_exec do
1184
- include ::Brick::RouteMapper
1185
- end
1186
-
1187
- # Do the root route before the Rails Welcome one would otherwise take precedence
1188
- if (route = ::Brick.config.default_route_fallback).present?
1189
- action = "#{route}#{'#index' unless route.index('#')}"
1190
- if ::Brick.config.path_prefix
1191
- ::Rails.application.routes.append do
1192
- send(:namespace, ::Brick.config.path_prefix) do
1193
- send(:root, action)
1194
- end
1195
- end
1196
- elsif ::Rails.application.routes.named_routes.send(:routes)[:root].nil?
1197
- ::Rails.application.routes.append do
1198
- send(:root, action)
1199
- end
1200
- end
1201
- ::Brick.established_drf = "/#{::Brick.config.path_prefix}#{action[action.index('#')..-1]}"
1202
- end
1203
- end
1204
-
1205
1178
  if Object.const_defined?('ActionView')
1206
1179
  require 'brick/frameworks/rails/form_tags'
1207
1180
  require 'brick/frameworks/rails/form_builder'
@@ -1551,7 +1524,7 @@ class Object
1551
1524
 
1552
1525
  private
1553
1526
 
1554
- def build_model(relations, base_module, base_name, class_name, inheritable_name = nil)
1527
+ def build_model(relations, base_module, base_name, class_name, inheritable_name = nil, is_generator = nil)
1555
1528
  tnp = ::Brick.config.table_name_prefixes&.find { |p| p.last == base_module.name }
1556
1529
  # return [base_module, ''] if !base_module.is_a?(Class) && base_name == tnp&.last
1557
1530
 
@@ -1585,12 +1558,12 @@ class Object
1585
1558
  # Maybe, just maybe there's a database table that will satisfy this need
1586
1559
  matching = ::Brick.table_name_lookup&.fetch(class_name, nil)
1587
1560
  if (matching ||= [table_name, singular_table_name, plural_class_name, model_name, table_name.titleize].find { |m| relations.key?(schema_name ? "#{schema_name}.#{m}" : m) })
1588
- build_model_worker(schema_name, inheritable_name, model_name, singular_table_name, table_name, relations, matching)
1561
+ build_model_worker(schema_name, inheritable_name, model_name, singular_table_name, table_name, relations, matching, is_generator)
1589
1562
  end
1590
1563
  end
1591
1564
  end
1592
1565
 
1593
- def build_model_worker(schema_name, inheritable_name, model_name, singular_table_name, table_name, relations, matching)
1566
+ def build_model_worker(schema_name, inheritable_name, model_name, singular_table_name, table_name, relations, matching, is_generator = nil)
1594
1567
  if ::Brick.apartment_multitenant &&
1595
1568
  schema_name == ::Brick.apartment_default_tenant
1596
1569
  relation = relations["#{schema_name}.#{matching}"]
@@ -1638,11 +1611,11 @@ class Object
1638
1611
  hmts = nil
1639
1612
  if (schema_module || Object).const_defined?((chosen_name = (inheritable_name || model_name)).to_sym)
1640
1613
  possible = (schema_module || Object).const_get(chosen_name)
1641
- return possible unless possible == schema_module
1614
+ return possible unless possible == schema_module || is_generator
1642
1615
  end
1643
1616
  code = +"class #{full_name} < #{base_model.name}\n"
1644
1617
  built_model = Class.new(base_model) do |new_model_class|
1645
- (schema_module || Object).const_set(chosen_name, new_model_class)
1618
+ (schema_module || Object).const_set(chosen_name, new_model_class) unless is_generator
1646
1619
  @_brick_relation = relation
1647
1620
  if inheritable_name
1648
1621
  new_model_class.define_singleton_method :inherited do |subclass|
@@ -1662,7 +1635,7 @@ class Object
1662
1635
  code << " has_secure_password\n"
1663
1636
  end
1664
1637
  # Accommodate singular or camel-cased table names such as "order_detail" or "OrderDetails"
1665
- code << " self.table_name = '#{self.table_name = matching}'\n" if inheritable_name || self.table_name != matching
1638
+ code << " self.table_name = '#{self.table_name = matching}'\n" if (inheritable_name || model_name).underscore.pluralize != matching
1666
1639
  if (inh_col = ::Brick.config.sti_type_column.find { |_k, v| v.include?(matching) }&.first)
1667
1640
  new_model_class.inheritance_column = inh_col
1668
1641
  code << " self.inheritance_column = '#{inh_col}'\n"
@@ -1799,6 +1772,18 @@ class Object
1799
1772
  new_model_class.send(:has_many, hmt_name.to_sym, **options)
1800
1773
  end
1801
1774
  end
1775
+
1776
+ # Auto-support Ransack if it's present
1777
+ if self.respond_to?(:ransackable_attributes)
1778
+ def self.ransackable_attributes(auth_object = nil)
1779
+ column_names + _ransackers.keys
1780
+ end
1781
+
1782
+ def self.ransackable_associations(auth_object = nil)
1783
+ reflect_on_all_associations.map { |a| a.name.to_s } + _ransackers.keys
1784
+ end
1785
+ end
1786
+
1802
1787
  code << "end # model #{full_name}\n"
1803
1788
  end # model class definition
1804
1789
  [built_model, code]
@@ -2618,9 +2603,9 @@ class Object
2618
2603
 
2619
2604
  def _brick_get_hm_assoc_name(relation, hm_assoc, source = nil)
2620
2605
  assoc_name, needs_class = if (relation[:hm_counts][hm_assoc[:inverse_table]]&.> 1) &&
2621
- hm_assoc[:alternate_name] != (source || name.underscore)
2606
+ hm_assoc[:alternate_name] != (source || name&.underscore)
2622
2607
  plural = "#{hm_assoc[:assoc_name]}_#{ActiveSupport::Inflector.pluralize(hm_assoc[:alternate_name])}"
2623
- new_alt_name = (hm_assoc[:alternate_name] == name.underscore) ? "#{hm_assoc[:assoc_name].singularize}_#{plural}" : plural
2608
+ new_alt_name = (hm_assoc[:alternate_name] == name&.underscore) ? "#{hm_assoc[:assoc_name].singularize}_#{plural}" : plural
2624
2609
  # %%% In rare cases might even need to add a number at the end for uniqueness
2625
2610
  # uniq = 1
2626
2611
  # while same_name = relation[:fks].find { |x| x.last[:assoc_name] == hm_assoc[:assoc_name] && x.last != hm_assoc }
@@ -3008,9 +2993,14 @@ module Brick
3008
2993
 
3009
2994
  def _brick_index(tbl_name, mode = nil, separator = nil, relation = nil, not_path = nil)
3010
2995
  separator ||= '_'
3011
- res_name = (tbl_name_parts = tbl_name.split('.'))[0..-2].first
3012
- res_name << '.' if res_name
3013
- (res_name ||= +'') << (relation ||= ::Brick.relations.fetch(tbl_name, nil))&.fetch(:resource, nil) || tbl_name_parts.last
2996
+ relation ||= ::Brick.relations.fetch(tbl_name, nil)
2997
+ if mode == :migration
2998
+ res_name = tbl_name
2999
+ else
3000
+ res_name = (tbl_name_parts = tbl_name.split('.'))[0..-2].first
3001
+ res_name << '.' if res_name
3002
+ (res_name ||= +'') << relation&.fetch(:resource, nil) || tbl_name_parts.last
3003
+ end
3014
3004
 
3015
3005
  res_parts = ((mode == :singular) ? res_name.singularize : res_name).split('.')
3016
3006
  res_parts.shift if ::Brick.apartment_multitenant && res_parts.length > 1 && res_parts.first == ::Brick.apartment_default_tenant
@@ -209,51 +209,95 @@ function linkSchemas() {
209
209
  # paths['app/models'] << 'lib/brick/frameworks/active_record/models'
210
210
  config.brick = ActiveSupport::OrderedOptions.new
211
211
  ActiveSupport.on_load(:before_initialize) do |app|
212
- if ::Rails.application.respond_to?(:reloader)
213
- ::Rails.application.reloader.to_prepare { Module.class_exec &::Brick::ADD_CONST_MISSING }
214
- else # For Rails < 5.0, just load it once at the start
215
- Module.class_exec &::Brick::ADD_CONST_MISSING
212
+
213
+ # --------------------------------------------
214
+ # 1. Load three initializers early
215
+ # (inflectsions.rb, brick.rb, apartment.rb)
216
+ # Very first thing, load inflections since we'll be using .pluralize and .singularize on table and model names
217
+ if File.exist?(inflections = ::Rails.root&.join('config/initializers/inflections.rb') || '')
218
+ load inflections
216
219
  end
217
220
  require 'brick/join_array'
218
- is_development = (ENV['RAILS_ENV'] || ENV['RACK_ENV']) == 'development'
219
- ::Brick.enable_models = app.config.brick.fetch(:enable_models, true)
220
- ::Brick.enable_controllers = app.config.brick.fetch(:enable_controllers, is_development)
221
- ::Brick.enable_views = app.config.brick.fetch(:enable_views, is_development)
222
- ::Brick.enable_routes = app.config.brick.fetch(:enable_routes, is_development)
223
- ::Brick.skip_database_views = app.config.brick.fetch(:skip_database_views, false)
224
-
225
- # Specific database tables and views to omit when auto-creating models
226
- ::Brick.exclude_tables = app.config.brick.fetch(:exclude_tables, [])
227
-
228
- # When table names have specific prefixes, automatically place them in their own module with a table_name_prefix.
229
- ::Brick.config.table_name_prefixes ||= app.config.brick.fetch(:table_name_prefixes, {})
230
-
231
- # Columns to treat as being metadata for purposes of identifying associative tables for has_many :through
232
- ::Brick.metadata_columns = app.config.brick.fetch(:metadata_columns, ['created_at', 'updated_at', 'deleted_at'])
233
-
234
- # Columns for which to add a validate presence: true even though the database doesn't have them marked as NOT NULL
235
- ::Brick.not_nullables = app.config.brick.fetch(:not_nullables, [])
236
-
237
- # Additional references (virtual foreign keys)
238
- ::Brick.additional_references = app.config.brick.fetch(:additional_references, nil)
239
-
240
- # Custom columns to add to a table, minimally defined with a name and DSL string
241
- ::Brick.custom_columns = app.config.brick.fetch(:custom_columns, nil)
242
-
243
- # When table names have specific prefixes, automatically place them in their own module with a table_name_prefix.
244
- ::Brick.order = app.config.brick.fetch(:order, {})
221
+ # Now the Brick initializer since there may be important schema things configured
222
+ if !::Brick.initializer_loaded && File.exist?(brick_initializer = ::Rails.root&.join('config/initializers/brick.rb') || '')
223
+ ::Brick.initializer_loaded = load brick_initializer
224
+
225
+ # After loading the initializer, add compatibility for ActiveStorage and ActionText if those haven't already been
226
+ # defined. (Further JSON configuration for ActiveStorage metadata happens later in the after_initialize hook.)
227
+ # begin
228
+ ['ActiveStorage', 'ActionText'].each do |ar_extension|
229
+ if Object.const_defined?(ar_extension) &&
230
+ (extension = Object.const_get(ar_extension)).respond_to?(:table_name_prefix) &&
231
+ !::Brick.config.table_name_prefixes.key?(as_tnp = extension.table_name_prefix)
232
+ ::Brick.config.table_name_prefixes[as_tnp] = ar_extension
233
+ end
234
+ end
235
+ # rescue # NoMethodError
236
+ # end
245
237
 
246
- # Skip creating a has_many association for these
247
- ::Brick.exclude_hms = app.config.brick.fetch(:exclude_hms, nil)
238
+ # Support the followability gem: https://github.com/nejdetkadir/followability
239
+ if Object.const_defined?('Followability') && !::Brick.config.table_name_prefixes.key?('followability_')
240
+ ::Brick.config.table_name_prefixes['followability_'] = 'Followability'
241
+ end
242
+ end
243
+ # Load the initializer for the Apartment gem a little early so that if .excluded_models and
244
+ # .default_schema are specified then we can work with non-tenanted models more appropriately
245
+ if (apartment = Object.const_defined?('Apartment')) &&
246
+ File.exist?(apartment_initializer = ::Rails.root.join('config/initializers/apartment.rb'))
247
+ require 'apartment/adapters/abstract_adapter'
248
+ Apartment::Adapters::AbstractAdapter.class_exec do
249
+ if instance_methods.include?(:process_excluded_models)
250
+ def process_excluded_models
251
+ # All other models will share a connection (at Apartment.connection_class) and we can modify at will
252
+ Apartment.excluded_models.each do |excluded_model|
253
+ begin
254
+ process_excluded_model(excluded_model)
255
+ rescue NameError => e
256
+ (@bad_models ||= []) << excluded_model
257
+ end
258
+ end
259
+ end
260
+ end
261
+ end
262
+ unless @_apartment_loaded
263
+ load apartment_initializer
264
+ @_apartment_loaded = true
265
+ end
266
+ end
248
267
 
249
- # Has one relationships
250
- ::Brick.has_ones = app.config.brick.fetch(:has_ones, nil)
268
+ if ::Brick.enable_routes? && Object.const_defined?('ActionDispatch')
269
+ require 'brick/route_mapper'
270
+ ActionDispatch::Routing::RouteSet.class_exec do
271
+ # In order to defer auto-creation of any routes that already exist, calculate Brick routes only after having loaded all others
272
+ prepend ::Brick::RouteSet
273
+ end
274
+ ActionDispatch::Routing::Mapper.class_exec do
275
+ include ::Brick::RouteMapper
276
+ end
251
277
 
252
- # accepts_nested_attributes_for relationships
253
- ::Brick.nested_attributes = app.config.brick.fetch(:nested_attributes, nil)
278
+ # Do the root route before the Rails Welcome one would otherwise take precedence
279
+ if (route = ::Brick.config.default_route_fallback).present?
280
+ action = "#{route}#{'#index' unless route.index('#')}"
281
+ if ::Brick.config.path_prefix
282
+ ::Rails.application.routes.append do
283
+ send(:namespace, ::Brick.config.path_prefix) do
284
+ send(:root, action)
285
+ end
286
+ end
287
+ elsif ::Rails.application.routes.named_routes.send(:routes)[:root].nil?
288
+ ::Rails.application.routes.append do
289
+ send(:root, action)
290
+ end
291
+ end
292
+ ::Brick.established_drf = "/#{::Brick.config.path_prefix}#{action[action.index('#')..-1]}"
293
+ end
294
+ end
254
295
 
255
- # Polymorphic associations
256
- ::Brick.polymorphics = app.config.brick.fetch(:polymorphics, nil)
296
+ if ::Rails.application.respond_to?(:reloader)
297
+ ::Rails.application.reloader.to_prepare { Module.class_exec &::Brick::ADD_CONST_MISSING }
298
+ else # For Rails < 5.0, just load it once at the start
299
+ Module.class_exec &::Brick::ADD_CONST_MISSING
300
+ end
257
301
  end
258
302
 
259
303
  # After we're initialized and before running the rest of stuff, put our configuration in place
@@ -497,20 +541,43 @@ window.addEventListener(\"popstate\", linkSchemas);
497
541
  end
498
542
  end
499
543
  end
500
- ::ActiveAdmin::Views::TitleBar.class_exec do
501
- alias _brick_build_title_tag build_title_tag
502
- def build_title_tag
503
- if klass = begin
504
- aa_id = helpers.instance_variable_get(:@current_tab)&.id
505
- ::Brick.relations.fetch(aa_id, nil)&.fetch(:class_name, nil)&.constantize
506
- rescue
507
- end
508
- h2((@title + link_to_brick(nil,
509
- BRICK_SVG.html_safe, # This would do well to be sized a bit smaller
510
- { title: "#{@_name} in Brick" }
511
- )).html_safe)
512
- else
513
- _brick_build_title_tag # Revert to the original
544
+ if (aav = ::ActiveAdmin::Views).const_defined?('TitleBar') # ActiveAdmin < 4.0
545
+ aav::TitleBar.class_exec do
546
+ alias _brick_build_title_tag build_title_tag
547
+ def build_title_tag
548
+ if klass = begin
549
+ aa_id = helpers.instance_variable_get(:@current_tab)&.id
550
+ ::Brick.relations.fetch(aa_id, nil)&.fetch(:class_name, nil)&.constantize
551
+ rescue
552
+ end
553
+ h2((@title + link_to_brick(nil,
554
+ BRICK_SVG.html_safe, # This would do well to be sized a bit smaller
555
+ { title: "#{@_name} in Brick" }
556
+ )).html_safe)
557
+ else
558
+ _brick_build_title_tag # Revert to the original
559
+ end
560
+ end
561
+ end
562
+ else # ActiveAdmin 4.0 or later
563
+ is_aa_4x = true
564
+ ::ActiveAdmin::ResourceController.class_exec do
565
+ include ActionView::Helpers::UrlHelper
566
+ include ::Brick::Rails::FormTags
567
+ alias _brick_default_page_title default_page_title
568
+ def default_page_title
569
+ dpt = _brick_default_page_title
570
+ if klass = begin
571
+ ::Brick.relations.fetch(@current_menu_item&.id, nil)&.fetch(:class_name, nil)&.constantize
572
+ rescue
573
+ end
574
+ (dpt + link_to_brick(nil,
575
+ BRICK_SVG.html_safe,
576
+ { title: "#{dpt} in Brick" }
577
+ )).html_safe
578
+ else
579
+ dpt
580
+ end
514
581
  end
515
582
  end
516
583
  end
@@ -523,9 +590,8 @@ window.addEventListener(\"popstate\", linkSchemas);
523
590
  div class: "blank_slate_container", id: "dashboard_default_message" do
524
591
  span class: "blank_slate" do
525
592
  span I18n.t("active_admin.dashboard_welcome.welcome")
526
- small I18n.t("active_admin.dashboard_welcome.call_to_action")
527
593
  end
528
- end
594
+ end unless is_aa_4x
529
595
  end
530
596
  end
531
597
  end
@@ -1402,7 +1468,7 @@ end %>#{"
1402
1468
  end
1403
1469
  \"<tr><td colspan=\\\"#\{td_count}\\\">Children: #\{child_links.join(' ')}</tr>\".html_safe
1404
1470
  end
1405
- %><%= if (page_num = @#{res_name = table_name.pluralize}._brick_page_num)
1471
+ %><%= if (page_num = @#{res_name = table_name.pluralize}&._brick_page_num)
1406
1472
  \"<tr><td colspan=\\\"#\{td_count}\\\">Page #\{page_num}</td></tr>\".html_safe
1407
1473
  end %></table>#{template_link}<%
1408
1474
  if description.present? %><span class=\"__brick\"><%=
@@ -1790,11 +1856,12 @@ flatpickr(\".timepicker\", {enableTime: true, noCalendar: true});
1790
1856
  <link rel=\"stylesheet\" type=\"text/css\" href=\"https://cdn.jsdelivr.net/npm/trix@2.0/dist/trix.min.css\">
1791
1857
  <% end %>
1792
1858
 
1793
- <% # Started with v0.14.4 of vanilla-jsoneditor
1859
+ <% # Good up until v0.19.0, and then with v0.20.0 of vanilla-jsoneditor started to get:
1860
+ # Uncaught TypeError: Failed to resolve module specifier \"immutable-json-patch\". Relative references must start with either \"/\", \"./\", or \"../\".
1794
1861
  if @_json_fields_present %>
1795
- <link rel=\"stylesheet\" type=\"text/css\" href=\"https://cdn.jsdelivr.net/npm/vanilla-jsoneditor/themes/jse-theme-default.min.css\">
1862
+ <link rel=\"stylesheet\" type=\"text/css\" href=\"https://cdn.jsdelivr.net/npm/vanilla-jsoneditor@0.19.0/themes/jse-theme-default.min.css\">
1796
1863
  <script type=\"module\">
1797
- import { JSONEditor } from \"https://cdn.jsdelivr.net/npm/vanilla-jsoneditor/index.min.js\";
1864
+ import { JSONEditor } from \"https://cdn.jsdelivr.net/npm/vanilla-jsoneditor@0.19.0/index.min.js\";
1798
1865
  document.querySelectorAll(\"input.jsonpicker\").forEach(function (inp) {
1799
1866
  var jsonDiv;
1800
1867
  if (jsonDiv = document.getElementById(\"_br_json_\" + inp.id)) {
@@ -69,8 +69,8 @@ module Brick::Rails::FormTags
69
69
 
70
70
  if show_aa_button != false && Object.const_defined?('ActiveAdmin')
71
71
  ActiveAdmin.application.namespaces.names.each do |ns|
72
- out << "
73
- <td>#{link_to_brick(
72
+ out << "
73
+ <td>#{link_to_brick(
74
74
  ::Brick::Rails::AA_PNG.html_safe,
75
75
  { index_proc: Proc.new do |aa_model, relation|
76
76
  path_helper = "#{ns}_#{relation.fetch(:auto_prefixed_schema, nil)}#{aa_model.model_name.route_key}_path".to_sym
@@ -31,61 +31,8 @@ module Brick
31
31
 
32
32
  orig_schema = nil
33
33
  if (relations = ::Brick.relations).keys == [:db_name]
34
- ::Brick.remove_instance_variable(:@_additional_references_loaded) if ::Brick.instance_variable_defined?(:@_additional_references_loaded)
34
+ # ::Brick.remove_instance_variable(:@_additional_references_loaded) if ::Brick.instance_variable_defined?(:@_additional_references_loaded)
35
35
 
36
- # --------------------------------------------
37
- # 1. Load three initializers early
38
- # (inflectsions.rb, brick.rb, apartment.rb)
39
- # Very first thing, load inflections since we'll be using .pluralize and .singularize on table and model names
40
- if File.exist?(inflections = ::Rails.root&.join('config/initializers/inflections.rb') || '')
41
- load inflections
42
- end
43
- # Now the Brick initializer since there may be important schema things configured
44
- if !::Brick.initializer_loaded && File.exist?(brick_initializer = ::Rails.root&.join('config/initializers/brick.rb') || '')
45
- ::Brick.initializer_loaded = load brick_initializer
46
-
47
- # After loading the initializer, add compatibility for ActiveStorage and ActionText if those haven't already been
48
- # defined. (Further JSON configuration for ActiveStorage metadata happens later in the after_initialize hook.)
49
- # begin
50
- ['ActiveStorage', 'ActionText'].each do |ar_extension|
51
- if Object.const_defined?(ar_extension) &&
52
- (extension = Object.const_get(ar_extension)).respond_to?(:table_name_prefix) &&
53
- !::Brick.config.table_name_prefixes.key?(as_tnp = extension.table_name_prefix)
54
- ::Brick.config.table_name_prefixes[as_tnp] = ar_extension
55
- end
56
- end
57
- # rescue # NoMethodError
58
- # end
59
-
60
- # Support the followability gem: https://github.com/nejdetkadir/followability
61
- if Object.const_defined?('Followability') && !::Brick.config.table_name_prefixes.key?('followability_')
62
- ::Brick.config.table_name_prefixes['followability_'] = 'Followability'
63
- end
64
- end
65
- # Load the initializer for the Apartment gem a little early so that if .excluded_models and
66
- # .default_schema are specified then we can work with non-tenanted models more appropriately
67
- if (apartment = Object.const_defined?('Apartment')) &&
68
- File.exist?(apartment_initializer = ::Rails.root.join('config/initializers/apartment.rb'))
69
- require 'apartment/adapters/abstract_adapter'
70
- Apartment::Adapters::AbstractAdapter.class_exec do
71
- if instance_methods.include?(:process_excluded_models)
72
- def process_excluded_models
73
- # All other models will share a connection (at Apartment.connection_class) and we can modify at will
74
- Apartment.excluded_models.each do |excluded_model|
75
- begin
76
- process_excluded_model(excluded_model)
77
- rescue NameError => e
78
- (@bad_models ||= []) << excluded_model
79
- end
80
- end
81
- end
82
- end
83
- end
84
- unless @_apartment_loaded
85
- load apartment_initializer
86
- @_apartment_loaded = true
87
- end
88
- end
89
36
  # Only for Postgres (Doesn't work in sqlite3 or MySQL)
90
37
  # puts ActiveRecord::Base.execute_sql("SELECT current_setting('SEARCH_PATH')").to_a.inspect
91
38
 
@@ -438,7 +385,7 @@ ORDER BY 1, 2, c.internal_column_id, acc.position"
438
385
  loop do
439
386
  klass = Object
440
387
  proposed_name_parts.each do |part|
441
- if klass.const_defined?(part)
388
+ if klass.const_defined?(part) && klass.name != part
442
389
  begin
443
390
  klass = klass.const_get(part)
444
391
  rescue NoMethodError => e
@@ -5,7 +5,7 @@ module Brick
5
5
  module VERSION
6
6
  MAJOR = 1
7
7
  MINOR = 0
8
- TINY = 203
8
+ TINY = 205
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
@@ -232,10 +232,6 @@ module Brick
232
232
  )
233
233
  )
234
234
  )
235
- # unless a.polymorphic? || (!a.belongs_to? && (through = a.options[:through])) ||
236
- # (a.klass && ::Brick.config.exclude_tables.exclude?(a.klass.table_name) &&
237
- # (!a.belongs_to? || (same_type = (fk_type = model_cols[a.foreign_key.to_s]&.type) == pk_type))
238
- # )
239
235
  if same_type == false # We really do want to test specifically for false here, and not nil!
240
236
  puts "WARNING:
241
237
  Foreign key column #{a.klass.table_name}.#{a.foreign_key} is #{fk_type}, but the primary key it relates to, #{primary_klass.table_name}.#{a_pk}, is #{pk_type}.
@@ -34,7 +34,6 @@ module Brick
34
34
 
35
35
  tbl_parts = rel.first.split('.')
36
36
  tbl_parts.shift if [::Brick.default_schema, 'public'].include?(tbl_parts.first)
37
- tbl_parts[-1] = tbl_parts[-1].pluralize
38
37
  begin
39
38
  s << ControllerOption.new(tbl_parts.join('/').camelize, rel.last[:class_name].constantize)
40
39
  rescue
@@ -64,7 +63,7 @@ module Brick
64
63
  else
65
64
  Object
66
65
  end
67
- controller_parts[controller_parts.length - 1] = (controller_name = "#{controller_parts.last.pluralize}Controller")
66
+ controller_parts[controller_parts.length - 1] = (controller_name = "#{controller_parts.last}Controller")
68
67
  _built_controller, code = Object.send(:build_controller, namespace, controller_name, controller_name, controller_option.model, relations)
69
68
  path = ['controllers']
70
69
  path.concat(controller_parts.map(&:underscore))
@@ -171,7 +171,7 @@ if ActiveRecord::Base.respond_to?(:brick_select) && !::Brick.initializer_loaded
171
171
 
172
172
  # # Custom path prefix to apply to all auto-generated Brick routes. Also causes auto-generated controllers
173
173
  # # to be created inside a module with the same name.
174
- # ::Brick.path_prefix = 'admin'
174
+ # ::Brick.path_prefix = 'brick'
175
175
 
176
176
  # # Normally all are enabled in development mode, and for security reasons only models are enabled in production
177
177
  # # and test. This allows you to either (a) turn off models entirely, or (b) enable controllers, views, and routes
@@ -110,7 +110,7 @@ module Brick
110
110
  end
111
111
  end
112
112
  # Start the timestamps back the same number of minutes from now as expected number of migrations to create
113
- current_mig_time = Time.now - (schemas.length + chosen.length).minutes
113
+ current_mig_time = [Time.now - (schemas.length + chosen.length).minutes]
114
114
  done = []
115
115
  fks = {}
116
116
  stuck = {}
@@ -139,12 +139,14 @@ module Brick
139
139
  # puts snag_fks.inspect
140
140
  stuck[tbl] = snags
141
141
  end
142
- end).present?
142
+ end
143
+ ).present?
143
144
  fringe.each do |tbl|
144
145
  mig = gen_migration_columns(relations, tbl, (tbl_parts = tbl.split('.')), (add_fks = []), built_schemas, mig_path, current_mig_time,
145
- key_type, is_4x_rails, ar_version, do_fks_last)
146
+ key_type, is_4x_rails, ar_version, do_fks_last, versions_to_create)
146
147
  after_fks.concat(add_fks) if do_fks_last
147
- versions_to_create << migration_file_write(mig_path, "create_#{::Brick._brick_index(tbl, nil, 'x')}", current_mig_time += 1.minute, ar_version, mig)
148
+ current_mig_time[0] += 1.minute
149
+ versions_to_create << migration_file_write(mig_path, "create_#{::Brick._brick_index(tbl, nil, 'x')}", current_mig_time, ar_version, mig)
148
150
  end
149
151
  done.concat(fringe)
150
152
  chosen -= done
@@ -154,9 +156,10 @@ module Brick
154
156
  # Write out any more tables that haven't been done yet
155
157
  chosen.each do |tbl|
156
158
  mig = gen_migration_columns(relations, tbl, (tbl_parts = tbl.split('.')), (add_fks = []), built_schemas, mig_path, current_mig_time,
157
- key_type, is_4x_rails, ar_version, do_fks_last)
159
+ key_type, is_4x_rails, ar_version, do_fks_last, versions_to_create)
158
160
  after_fks.concat(add_fks)
159
- migration_file_write(mig_path, "create_#{::Brick._brick_index(tbl, nil, 'x')}", current_mig_time += 1.minute, ar_version, mig)
161
+ current_mig_time[0] += 1.minute
162
+ versions_to_create << migration_file_write(mig_path, "create_#{::Brick._brick_index(tbl, :migration, 'x')}", current_mig_time, ar_version, mig)
160
163
  end
161
164
  done.concat(chosen)
162
165
  chosen.clear
@@ -188,7 +191,8 @@ module Brick
188
191
  end\n"
189
192
  end
190
193
  mig << +" end\n"
191
- migration_file_write(mig_path, 'create_brick_fks.rbx', current_mig_time += 1.minute, ar_version, mig)
194
+ current_mig_time[0] += 1.minute
195
+ versions_to_create << migration_file_write(mig_path, 'create_brick_fks.rbx', current_mig_time, ar_version, mig)
192
196
  puts "Have written out a final migration called 'create_brick_fks.rbx' which creates #{after_fks.length} foreign keys.
193
197
  This file extension (.rbx) will cause it not to run yet when you do a 'rails db:migrate'.
194
198
  The idea here is to do all data loading first, and then rename that migration file back
@@ -255,7 +259,7 @@ module Brick
255
259
  private
256
260
 
257
261
  def gen_migration_columns(relations, tbl, tbl_parts, add_fks, built_schemas, mig_path, current_mig_time,
258
- key_type, is_4x_rails, ar_version, do_fks_last)
262
+ key_type, is_4x_rails, ar_version, do_fks_last, versions_to_create)
259
263
  return unless (relation = relations.fetch(tbl, nil))&.fetch(:cols, nil)&.present?
260
264
 
261
265
  mig = +''
@@ -278,7 +282,8 @@ module Brick
278
282
  end
279
283
  unless schema.blank? || built_schemas.key?(schema)
280
284
  mig = +" def change\n create_schema(:#{schema}) unless schema_exists?(:#{schema})\n end\n"
281
- migration_file_write(mig_path, "create_db_schema_#{schema.underscore}", current_mig_time += 1.minute, ar_version, mig)
285
+ current_mig_time[0] += 1.minute
286
+ versions_to_create << migration_file_write(mig_path, "create_db_schema_#{schema.underscore}", current_mig_time, ar_version, mig)
282
287
  built_schemas[schema] = nil
283
288
  end
284
289
 
@@ -389,11 +394,11 @@ module Brick
389
394
  end
390
395
  end
391
396
  if possible_ts.length == 2 && # Both created_at and updated_at
392
- # Rails 5 and later timestamps default to NOT NULL
393
- (possible_ts.first.last == is_4x_rails && possible_ts.last.last == is_4x_rails)
397
+ # Rails 5 and later timestamps default to NOT NULL
398
+ (possible_ts.first.last == is_4x_rails && possible_ts.last.last == is_4x_rails)
394
399
  mig << "\n t.timestamps\n"
395
400
  else # Just one or the other, or a nullability mismatch
396
- possible_ts.each { |ts| emit_column('timestamp', ts.first, nil) }
401
+ possible_ts.each { |ts| mig << emit_column('timestamp', ts.first, nil) }
397
402
  end
398
403
  mig << " end\n"
399
404
  if pk_is_also_fk
@@ -424,7 +429,7 @@ module Brick
424
429
  end
425
430
 
426
431
  def migration_file_write(mig_path, name, current_mig_time, ar_version, mig)
427
- File.open("#{mig_path}/#{version = current_mig_time.strftime('%Y%m%d%H%M00')}_#{name}#{'.rb' unless name.index('.')}", "w") do |f|
432
+ File.open("#{mig_path}/#{version = current_mig_time.first.strftime('%Y%m%d%H%M00')}_#{name}#{'.rb' unless name.index('.')}", "w") do |f|
428
433
  f.write "class #{name.split('.').first.camelize} < ActiveRecord::Migration#{ar_version}\n"
429
434
  f.write mig
430
435
  f.write "end\n"
@@ -62,7 +62,7 @@ module Brick
62
62
  else
63
63
  Object
64
64
  end
65
- _built_model, code = Object.send(:build_model, relations, base_module, base_module.name, model_parts.last)
65
+ _built_model, code = Object.send(:build_model, relations, base_module, base_module.name, model_parts.last, nil, true)
66
66
  path = ['models']
67
67
  path.concat(model_parts.map(&:underscore))
68
68
  dir = +"#{::Rails.root}/app"
@@ -27,7 +27,7 @@ module Brick
27
27
  # Generate a list of viable models that can be chosen
28
28
  # First start with any existing models that have been defined ...
29
29
  existing_models = ActiveRecord::Base.descendants.each_with_object({}) do |m, s|
30
- s[m.table_name] = SeedModel.new(m.table_name, m, false) if !m.abstract_class? && m.table_exists?
30
+ s[m.table_name] = SeedModel.new(m.table_name, m, false) if !m.abstract_class? && !m.is_view? && m.table_exists?
31
31
  end
32
32
  models = (existing_models.values +
33
33
  # ... then add models which can be auto-built by Brick
@@ -123,12 +123,15 @@ module Brick
123
123
  pk_val = obj.send(pkey_cols.first)
124
124
  fk_vals = []
125
125
  data = []
126
- relation[:cols].each do |col, col_type|
126
+ relation[:cols].each do |col, _col_type|
127
127
  next if !(fk = fkeys.find { |assoc| col == assoc[:fk] }) &&
128
128
  pkey_cols.include?(col)
129
129
 
130
- if (val = obj.send(col)) && (val.is_a?(Time) || val.is_a?(Date))
131
- val = val.to_s
130
+ begin
131
+ if (val = obj.send(col)) && (val.is_a?(Time) || val.is_a?(Date))
132
+ val = val.to_s
133
+ end
134
+ rescue StandardError => e # ActiveRecord::Encryption::Errors::Configuration
132
135
  end
133
136
  if fk
134
137
  inv_tbl = fk[:inverse_table].gsub('.', '__')
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.203
4
+ version: 1.0.205
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lorin Thwaits
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-02-07 00:00:00.000000000 Z
11
+ date: 2024-02-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -285,7 +285,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
285
285
  - !ruby/object:Gem::Version
286
286
  version: 1.3.6
287
287
  requirements: []
288
- rubygems_version: 3.2.33
288
+ rubygems_version: 3.1.6
289
289
  signing_key:
290
290
  specification_version: 4
291
291
  summary: Create a Rails app from data alone