brick 1.0.18 → 1.0.19
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/brick/extensions.rb +41 -23
- data/lib/brick/frameworks/rails/engine.rb +20 -26
- data/lib/brick/version_number.rb +1 -1
- data/lib/brick.rb +11 -0
- data/lib/generators/brick/install_generator.rb +2 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 57a1d4e3774c90984cfc435d9ed87e42b74c364b01fd7ced7df740f5005b935e
|
4
|
+
data.tar.gz: 8222088ef88ca48cd90144c8503638644195f2d593ff95d7b2e3530304ac6fb2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2b785c34e1a21563232ae54f6af25989fe02b73f92eb1327b27d6f21e80b7e353a5995305c4c1188dda885465a196f87fb5979a13c3e6a0219d4895dc59593dd
|
7
|
+
data.tar.gz: bd2018d48dad15f51d7a87e39d2710bde9a5becbe969e741004bf730f57faecbd84a81a2f75cfdd60c2ff48f239fe6c5c8d3f47b4b2f79e355b7f100f9bb7943
|
data/lib/brick/extensions.rb
CHANGED
@@ -137,7 +137,6 @@ module ActiveRecord
|
|
137
137
|
alias _brick_find_sti_class find_sti_class
|
138
138
|
def find_sti_class(type_name)
|
139
139
|
if ::Brick.sti_models.key?(type_name)
|
140
|
-
# puts ['X', self.name, type_name].inspect
|
141
140
|
_brick_find_sti_class(type_name)
|
142
141
|
else
|
143
142
|
# This auto-STI is more of a brute-force approach, building modules where needed
|
@@ -149,7 +148,7 @@ module ActiveRecord
|
|
149
148
|
if ::Brick.config.sti_namespace_prefixes&.key?("::#{module_name}::") ||
|
150
149
|
::Brick.config.sti_namespace_prefixes&.key?("#{module_name}::")
|
151
150
|
_brick_find_sti_class(type_name)
|
152
|
-
elsif File.
|
151
|
+
elsif File.exist?(candidate_file = Rails.root.join('app/models' + module_prefixes.map(&:underscore).join('/') + '.rb'))
|
153
152
|
_brick_find_sti_class(type_name) # Find this STI class normally
|
154
153
|
else
|
155
154
|
# Build missing prefix modules if they don't yet exist
|
@@ -243,10 +242,10 @@ class Object
|
|
243
242
|
|
244
243
|
# Adjust for STI if we know of a base model for the requested model name
|
245
244
|
table_name = if (base_model = ::Brick.sti_models[model_name]&.fetch(:base, nil))
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
245
|
+
base_model.table_name
|
246
|
+
else
|
247
|
+
ActiveSupport::Inflector.pluralize(singular_table_name)
|
248
|
+
end
|
250
249
|
|
251
250
|
# Maybe, just maybe there's a database table that will satisfy this need
|
252
251
|
if (matching = [table_name, singular_table_name, plural_class_name, model_name].find { |m| relations.key?(m) })
|
@@ -522,9 +521,9 @@ module ActiveRecord::ConnectionHandling
|
|
522
521
|
end
|
523
522
|
|
524
523
|
def _brick_reflect_tables
|
525
|
-
|
526
|
-
|
527
|
-
|
524
|
+
if (relations = ::Brick.relations).empty?
|
525
|
+
# Only for Postgres? (Doesn't work in sqlite3)
|
526
|
+
# puts ActiveRecord::Base.connection.execute("SELECT current_setting('SEARCH_PATH')").to_a.inspect
|
528
527
|
|
529
528
|
schema_sql = 'SELECT NULL AS table_schema;'
|
530
529
|
case ActiveRecord::Base.connection.adapter_name
|
@@ -614,6 +613,25 @@ module ActiveRecord::ConnectionHandling
|
|
614
613
|
end
|
615
614
|
end
|
616
615
|
|
616
|
+
# # Add unique OIDs
|
617
|
+
# if ActiveRecord::Base.connection.adapter_name == 'PostgreSQL'
|
618
|
+
# ActiveRecord::Base.execute_sql(
|
619
|
+
# "SELECT c.oid, n.nspname, c.relname
|
620
|
+
# FROM pg_catalog.pg_namespace AS n
|
621
|
+
# INNER JOIN pg_catalog.pg_class AS c ON n.oid = c.relnamespace
|
622
|
+
# WHERE c.relkind IN ('r', 'v')"
|
623
|
+
# ).each do |r|
|
624
|
+
# next if ['pg_catalog', 'information_schema', ''].include?(r['nspname']) ||
|
625
|
+
# ['ar_internal_metadata', 'schema_migrations'].include?(r['relname'])
|
626
|
+
# relation = relations.fetch(r['relname'], nil)
|
627
|
+
# if relation
|
628
|
+
# (relation[:oid] ||= {})[r['nspname']] = r['oid']
|
629
|
+
# else
|
630
|
+
# puts "Where is #{r['nspname']} #{r['relname']} ?"
|
631
|
+
# end
|
632
|
+
# end
|
633
|
+
# end
|
634
|
+
|
617
635
|
case ActiveRecord::Base.connection.adapter_name
|
618
636
|
when 'PostgreSQL', 'Mysql2'
|
619
637
|
sql = ActiveRecord::Base.send(:sanitize_sql_array, [
|
@@ -706,7 +724,7 @@ module Brick
|
|
706
724
|
missing << fk[0] unless relations.key?(fk[0])
|
707
725
|
missing << primary_table unless is_class || relations.key?(primary_table)
|
708
726
|
unless missing.empty?
|
709
|
-
tables = relations.reject { |
|
727
|
+
tables = relations.reject { |_k, v| v.fetch(:isView, nil) }.keys.sort
|
710
728
|
puts "Brick: Additional reference #{fk.inspect} refers to non-existent #{'table'.pluralize(missing.length)} #{missing.join(' and ')}. (Available tables include #{tables.join(', ')}.)"
|
711
729
|
return
|
712
730
|
end
|
@@ -715,7 +733,7 @@ module Brick
|
|
715
733
|
puts "Brick: Additional reference #{fk.inspect} refers to non-existent column #{fk[1]}. (Columns present in #{fk[0]} are #{columns.join(', ')}.)"
|
716
734
|
return
|
717
735
|
end
|
718
|
-
if (redundant = bts.find { |
|
736
|
+
if (redundant = bts.find { |_k, v| v[:inverse]&.fetch(:inverse_table, nil) == fk[0] && v[:fk] == fk[1] && v[:inverse_table] == primary_table })
|
719
737
|
if is_class && !redundant.last.key?(:class)
|
720
738
|
redundant.last[:primary_class] = primary_class # Round out this BT so it can find the proper :source for a HMT association that references an STI subclass
|
721
739
|
else
|
@@ -737,19 +755,19 @@ module Brick
|
|
737
755
|
# assoc_bt[:inverse_of] = primary_class.reflect_on_all_associations.find { |a| a.foreign_key == bt[1] }
|
738
756
|
end
|
739
757
|
|
740
|
-
|
741
|
-
|
742
|
-
|
743
|
-
|
744
|
-
|
745
|
-
|
746
|
-
|
747
|
-
|
748
|
-
|
749
|
-
|
750
|
-
|
751
|
-
assoc_bt[:inverse] = assoc_hm
|
758
|
+
return if is_class || ::Brick.config.exclude_hms&.any? { |exclusion| fk[0] == exclusion[0] && fk[1] == exclusion[1] && primary_table == exclusion[2] }
|
759
|
+
|
760
|
+
cnstr_name = "hm_#{cnstr_name}"
|
761
|
+
if (assoc_hm = hms.fetch(cnstr_name, nil))
|
762
|
+
assoc_hm[:fk] = assoc_hm[:fk].is_a?(String) ? [assoc_hm[:fk], fk[1]] : assoc_hm[:fk].concat(fk[1])
|
763
|
+
assoc_hm[:alternate_name] = "#{assoc_hm[:alternate_name]}_#{bt_assoc_name}" unless assoc_hm[:alternate_name] == bt_assoc_name
|
764
|
+
assoc_hm[:inverse] = assoc_bt
|
765
|
+
else
|
766
|
+
assoc_hm = hms[cnstr_name] = { is_bt: false, fk: fk[1], assoc_name: fk[0], alternate_name: bt_assoc_name, inverse_table: fk[0], inverse: assoc_bt }
|
767
|
+
hm_counts = relation.fetch(:hm_counts) { relation[:hm_counts] = {} }
|
768
|
+
hm_counts[fk[0]] = hm_counts.fetch(fk[0]) { 0 } + 1
|
752
769
|
end
|
770
|
+
assoc_bt[:inverse] = assoc_hm
|
753
771
|
# hms[cnstr_name] << { is_bt: false, fk: fk[1], assoc_name: fk[0], alternate_name: bt_assoc_name, inverse_table: fk[0] }
|
754
772
|
end
|
755
773
|
end
|
@@ -51,14 +51,11 @@ module Brick
|
|
51
51
|
# Need to return true if we can fill in the blanks for a missing one
|
52
52
|
# args will be something like: ["index", ["categories"]]
|
53
53
|
model = args[1].map(&:camelize).join('::').singularize.constantize
|
54
|
-
if (
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
)
|
60
|
-
)
|
61
|
-
instance_variable_set(:@_brick_model, model)
|
54
|
+
if is_template_exists = model && (
|
55
|
+
['index', 'show'].include?(args.first) || # Everything has index and show
|
56
|
+
# Only CRU stuff has create / update / destroy
|
57
|
+
(!model.is_view? && ['new', 'create', 'edit', 'update', 'destroy'].include?(args.first))
|
58
|
+
) && instance_variable_set(:@_brick_model, model)
|
62
59
|
end
|
63
60
|
end
|
64
61
|
is_template_exists
|
@@ -88,9 +85,6 @@ module Brick
|
|
88
85
|
end
|
89
86
|
end
|
90
87
|
|
91
|
-
schema_options = ::Brick.db_schemas.each_with_object(+'') { |v, s| s << "<option value=\"#{v}\">#{v}</option>" }.html_safe
|
92
|
-
table_options = (::Brick.relations.keys - ::Brick.config.exclude_tables)
|
93
|
-
.each_with_object(+'') { |v, s| s << "<option value=\"#{v}\">#{v}</option>" }.html_safe
|
94
88
|
hms_columns = +'' # Used for 'index'
|
95
89
|
hms_headers = hms.each_with_object([]) do |hm, s|
|
96
90
|
next if exclude_hms.key?((hm_assoc = hm.last).name)
|
@@ -114,7 +108,13 @@ module Brick
|
|
114
108
|
end
|
115
109
|
s << [hm_assoc, "H#{hm_assoc.macro == :has_one ? 'O' : 'M'}#{'T' if hm_assoc.options[:through]} #{hm.first}"]
|
116
110
|
end
|
117
|
-
|
111
|
+
end
|
112
|
+
if @_brick_model
|
113
|
+
schema_options = ::Brick.db_schemas.each_with_object(+'') { |v, s| s << "<option value=\"#{v}\">#{v}</option>" }.html_safe
|
114
|
+
# %%% If we are not auto-creating controllers (or routes) then omit by default, and if enabled anyway, such as in a development
|
115
|
+
# environment or whatever, then get either the controllers or routes list instead
|
116
|
+
table_options = (::Brick.relations.keys - ::Brick.config.exclude_tables)
|
117
|
+
.each_with_object(+'') { |v, s| s << "<option value=\"#{v.underscore.pluralize}\">#{v}</option>" }.html_safe
|
118
118
|
css = "<style>
|
119
119
|
table {
|
120
120
|
border-collapse: collapse;
|
@@ -253,7 +253,7 @@ function changeout(href, param, value) {
|
|
253
253
|
<h1>#{model_name.pluralize}</h1>
|
254
254
|
<% if @_brick_params&.present? %><h3>where <%= @_brick_params.each_with_object([]) { |v, s| s << \"#\{v.first\} = #\{v.last.inspect\}\" }.join(', ') %></h3><% end %>
|
255
255
|
<table id=\"#{table_name}\">
|
256
|
-
<thead><tr>#{"<th></th>" if pk
|
256
|
+
<thead><tr>#{"<th></th>" if pk}
|
257
257
|
<% bts = { #{bts.each_with_object([]) { |v, s| s << "#{v.first.inspect} => [#{v.last.first.inspect}, #{v.last[1].name}, #{v.last[1].primary_key.inspect}]"}.join(', ')} }
|
258
258
|
@#{table_name}.columns.map(&:name).each do |col| %>
|
259
259
|
<% next if col == '#{pk}' || ::Brick.config.metadata_columns.include?(col) %>
|
@@ -271,7 +271,7 @@ function changeout(href, param, value) {
|
|
271
271
|
<tbody>
|
272
272
|
<% @#{table_name}.each do |#{obj_name}| %>
|
273
273
|
<tr>#{"
|
274
|
-
<td><%= link_to '⇛', #{obj_name}_path(#{obj_name}.#{pk}), { class: 'big-arrow' } %></td>" if pk
|
274
|
+
<td><%= link_to '⇛', #{obj_name}_path(#{obj_name}.#{pk}), { class: 'big-arrow' } %></td>" if pk}
|
275
275
|
<% #{obj_name}.attributes.each do |k, val| %>
|
276
276
|
<% next if k == '#{pk}' || ::Brick.config.metadata_columns.include?(k) %>
|
277
277
|
<td>
|
@@ -341,8 +341,13 @@ function changeout(href, param, value) {
|
|
341
341
|
<% end %>
|
342
342
|
<% when :boolean %>
|
343
343
|
<%= f.check_box k.to_sym %>
|
344
|
-
<% when :integer, :date, :datetime, :
|
344
|
+
<% when :integer, :decimal, :float, :date, :datetime, :time, :timestamp
|
345
|
+
# What happens when keys are UUID?
|
346
|
+
# Postgres naturally uses the +uuid_generate_v4()+ function from the uuid-ossp extension
|
347
|
+
# If it's not yet enabled then: enable_extension 'uuid-ossp'
|
348
|
+
# ActiveUUID gem created a new :uuid type %>
|
345
349
|
<%= val %>
|
350
|
+
<% when :binary, :primary_key %>
|
346
351
|
<% end %>
|
347
352
|
<% end %>
|
348
353
|
</td>
|
@@ -391,17 +396,6 @@ function changeout(href, param, value) {
|
|
391
396
|
# Just in case it hadn't been done previously when we tried to load the brick initialiser,
|
392
397
|
# go make sure we've loaded additional references (virtual foreign keys).
|
393
398
|
::Brick.load_additional_references
|
394
|
-
|
395
|
-
# Find associative tables that can be set up for has_many :through
|
396
|
-
::Brick.relations.each do |_key, tbl|
|
397
|
-
tbl_cols = tbl[:cols].keys
|
398
|
-
fks = tbl[:fks].each_with_object({}) { |fk, s| s[fk.last[:fk]] = [fk.last[:assoc_name], fk.last[:inverse_table]] if fk.last[:is_bt]; s }
|
399
|
-
# Aside from the primary key and the metadata columns created_at, updated_at, and deleted_at, if this table only has
|
400
|
-
# foreign keys then it can act as an associative table and thus be used with has_many :through.
|
401
|
-
if fks.length > 1 && (tbl_cols - fks.keys - (::Brick.config.metadata_columns || []) - (tbl[:pkey].values.first || [])).length.zero?
|
402
|
-
fks.each { |fk| tbl[:hmt_fks][fk.first] = fk.last }
|
403
|
-
end
|
404
|
-
end
|
405
399
|
end
|
406
400
|
end
|
407
401
|
end
|
data/lib/brick/version_number.rb
CHANGED
data/lib/brick.rb
CHANGED
@@ -254,6 +254,17 @@ module Brick
|
|
254
254
|
ars.each { |fk| ::Brick._add_bt_and_hm(fk[0..2]) }
|
255
255
|
@_additional_references_loaded = true
|
256
256
|
end
|
257
|
+
|
258
|
+
# Find associative tables that can be set up for has_many :through
|
259
|
+
::Brick.relations.each do |_key, tbl|
|
260
|
+
tbl_cols = tbl[:cols].keys
|
261
|
+
fks = tbl[:fks].each_with_object({}) { |fk, s| s[fk.last[:fk]] = [fk.last[:assoc_name], fk.last[:inverse_table]] if fk.last[:is_bt]; s }
|
262
|
+
# Aside from the primary key and the metadata columns created_at, updated_at, and deleted_at, if this table only has
|
263
|
+
# foreign keys then it can act as an associative table and thus be used with has_many :through.
|
264
|
+
if fks.length > 1 && (tbl_cols - fks.keys - (::Brick.config.metadata_columns || []) - (tbl[:pkey].values.first || [])).length.zero?
|
265
|
+
fks.each { |fk| tbl[:hmt_fks][fk.first] = fk.last }
|
266
|
+
end
|
267
|
+
end
|
257
268
|
end
|
258
269
|
|
259
270
|
|
@@ -18,7 +18,7 @@ module Brick
|
|
18
18
|
desc 'Generates an initializer file for configuring Brick'
|
19
19
|
|
20
20
|
def create_initializer_file
|
21
|
-
unless File.
|
21
|
+
unless File.exist?(filename = 'config/initializers/brick.rb')
|
22
22
|
# See if we can make suggestions for additional_references
|
23
23
|
resembles_fks = []
|
24
24
|
possible_additional_references = (relations = ::Brick.relations).each_with_object([]) do |v, s|
|
@@ -47,7 +47,7 @@ module Brick
|
|
47
47
|
if (relations.fetch(f_table = col_down, nil) ||
|
48
48
|
relations.fetch(f_table = ActiveSupport::Inflector.pluralize(col_down), nil)) &&
|
49
49
|
# Looks pretty promising ... just make sure a model file isn't present
|
50
|
-
!File.
|
50
|
+
!File.exist?("app/models/#{ActiveSupport::Inflector.singularize(v.first)}.rb")
|
51
51
|
s << "['#{v.first}', '#{col}', '#{f_table}']"
|
52
52
|
else
|
53
53
|
resembles_fks << "#{v.first}.#{col}"
|
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.19
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lorin Thwaits
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-04-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|