brick 1.0.203 → 1.0.205

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