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 +4 -4
- data/lib/brick/config.rb +3 -3
- data/lib/brick/extensions.rb +33 -43
- data/lib/brick/frameworks/rails/engine.rb +126 -59
- data/lib/brick/frameworks/rails/form_tags.rb +2 -2
- data/lib/brick/reflect_tables.rb +2 -55
- data/lib/brick/version_number.rb +1 -1
- data/lib/brick.rb +0 -4
- data/lib/generators/brick/controllers_generator.rb +1 -2
- data/lib/generators/brick/install_generator.rb +1 -1
- data/lib/generators/brick/migration_builder.rb +18 -13
- data/lib/generators/brick/models_generator.rb +1 -1
- data/lib/generators/brick/seeds_generator.rb +7 -4
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3abdf25aeb401676febcc1ea98ce104a9e005ecae652f17daf3736baab63d5ea
|
4
|
+
data.tar.gz: 195eb8e27607f719808954914a409b356c249384cacd0535fab65652b02cd4ec
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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)
|
data/lib/brick/extensions.rb
CHANGED
@@ -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
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
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 ||
|
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
|
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
|
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
|
-
|
3012
|
-
|
3013
|
-
|
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
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
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
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
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
|
-
|
247
|
-
|
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
|
-
|
250
|
-
|
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
|
-
|
253
|
-
|
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
|
-
|
256
|
-
|
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
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
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}
|
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
|
-
<% #
|
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
|
-
|
73
|
-
|
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
|
data/lib/brick/reflect_tables.rb
CHANGED
@@ -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
|
data/lib/brick/version_number.rb
CHANGED
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
|
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 = '
|
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
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
393
|
-
|
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,
|
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
|
-
|
131
|
-
val = val.
|
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.
|
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-
|
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.
|
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
|