brick 1.0.2 → 1.0.3
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 +22 -3
- data/lib/brick/frameworks/rails/engine.rb +136 -120
- data/lib/brick/version_number.rb +1 -1
- 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: ff255b32c913dbb0e02d3f197d035faf43dc44afc4041cda3f57e92fc9df893a
|
4
|
+
data.tar.gz: 763b5579402a7668abf3d266665879643b8d44ed04686a35f2df145b1ddfee72
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f513e360dcba221bbd5061eb2ef3ef349a7c18ec6babae32273e877ba5b8cd0071f337f11c63460157afaa55cb0e8eea7dc99d80f64231270fc76218ef84397e
|
7
|
+
data.tar.gz: eb684612e551f8c884b618985884ad88b5ed827680fb4056f91f6c575fb479d18b92e6d4fa6de222ec24a7991f419723447313780fdbe5b7a0a903561dcb3dd7
|
data/lib/brick/extensions.rb
CHANGED
@@ -55,19 +55,38 @@ module ActiveRecord
|
|
55
55
|
class Relation
|
56
56
|
def brick_where(params)
|
57
57
|
wheres = {}
|
58
|
+
rel_joins = []
|
58
59
|
params.each do |k, v|
|
59
|
-
|
60
|
+
if (ks = k.split('.')).length > 1
|
61
|
+
assoc_name = ks.first.to_sym
|
62
|
+
# Make sure it's a good association name and that the model has that column name
|
63
|
+
next unless klass.reflect_on_association(assoc_name)&.klass&.columns&.map(&:name)&.include?(ks.last)
|
60
64
|
|
65
|
+
rel_joins << assoc_name unless rel_joins.include?(assoc_name)
|
66
|
+
else
|
67
|
+
next unless klass._brick_get_fks.include?(k)
|
68
|
+
end
|
61
69
|
wheres[k] = v.split(',')
|
62
70
|
end
|
63
71
|
unless wheres.empty?
|
64
72
|
where!(wheres)
|
73
|
+
joins!(rel_joins) unless rel_joins.empty?
|
65
74
|
wheres # Return the specific parameters that we did use
|
66
75
|
end
|
67
76
|
end
|
68
77
|
end
|
69
78
|
end
|
70
79
|
|
80
|
+
# Rails::Application.class_exec do
|
81
|
+
# alias _brick_initialize! initialize!
|
82
|
+
# # Run Before initialize make sure our settings
|
83
|
+
# def initialize!
|
84
|
+
# # initialization code goes here
|
85
|
+
# puts "BEFORE1"
|
86
|
+
# _brick_initialize!
|
87
|
+
# end
|
88
|
+
# end
|
89
|
+
|
71
90
|
# Object.class_exec do
|
72
91
|
class Object
|
73
92
|
class << self
|
@@ -334,9 +353,9 @@ module ActiveRecord::ConnectionHandling
|
|
334
353
|
ActiveRecord::Base.connection.execute(sql).values.each { |fk| ::Brick._add_bt_and_hm(fk, relations) }
|
335
354
|
end
|
336
355
|
|
337
|
-
puts "Classes built from tables:"
|
356
|
+
puts "Classes that can be built from tables:"
|
338
357
|
relations.select { |_k, v| !v.key?(:isView) }.keys.each { |k| puts ActiveSupport::Inflector.singularize(k).camelize }
|
339
|
-
puts "Classes built from views:"
|
358
|
+
puts "Classes that can be built from views:"
|
340
359
|
relations.select { |_k, v| v.key?(:isView) }.keys.each { |k| puts ActiveSupport::Inflector.singularize(k).camelize }
|
341
360
|
# pp relations; nil
|
342
361
|
|
@@ -5,78 +5,103 @@ module Brick
|
|
5
5
|
# See http://guides.rubyonrails.org/engines.html
|
6
6
|
class Engine < ::Rails::Engine
|
7
7
|
# paths['app/models'] << 'lib/brick/frameworks/active_record/models'
|
8
|
+
puts "BEFORE - engine set config"
|
8
9
|
config.brick = ActiveSupport::OrderedOptions.new
|
9
|
-
initializer 'brick.initialisation' do |app|
|
10
|
-
|
11
|
-
|
10
|
+
# initializer 'brick.initialisation' do |app|
|
11
|
+
ActiveSupport.on_load(:before_initialize) do |app|
|
12
|
+
puts "BEFORE - engine initialisation"
|
13
|
+
::Brick.enable_models = app.config.brick.fetch(:enable_models, true)
|
14
|
+
::Brick.enable_controllers = app.config.brick.fetch(:enable_controllers, true)
|
15
|
+
::Brick.enable_views = app.config.brick.fetch(:enable_views, true)
|
16
|
+
::Brick.enable_routes = app.config.brick.fetch(:enable_routes, true)
|
17
|
+
::Brick.skip_database_views = app.config.brick.fetch(:skip_database_views, false)
|
18
|
+
|
19
|
+
# Specific database tables and views to omit when auto-creating models
|
20
|
+
::Brick.exclude_tables = app.config.brick.fetch(:exclude_tables, [])
|
21
|
+
|
22
|
+
# Columns to treat as being metadata for purposes of identifying associative tables for has_many :through
|
23
|
+
::Brick.metadata_columns = app.config.brick.fetch(:metadata_columns, ['created_at', 'updated_at', 'deleted_at'])
|
24
|
+
|
25
|
+
# Additional references (virtual foreign keys)
|
26
|
+
::Brick.additional_references = app.config.brick.fetch(:additional_references, nil)
|
12
27
|
|
13
|
-
#
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
28
|
+
# After we're initialized and before running the rest of stuff, put our configuration in place
|
29
|
+
ActiveSupport.on_load(:after_initialize) do |xyz|
|
30
|
+
puts "AFTER - engine initialisation"
|
31
|
+
# ====================================
|
32
|
+
# Dynamically create generic templates
|
33
|
+
# ====================================
|
34
|
+
if ::Brick.enable_views?
|
35
|
+
ActionView::LookupContext.class_exec do
|
36
|
+
alias :_brick_template_exists? :template_exists?
|
37
|
+
def template_exists?(*args, **options)
|
38
|
+
unless (is_template_exists = _brick_template_exists?(*args, **options))
|
39
|
+
# Need to return true if we can fill in the blanks for a missing one
|
40
|
+
# args will be something like: ["index", ["categories"]]
|
41
|
+
model = args[1].map(&:camelize).join('::').singularize.constantize
|
42
|
+
if (
|
43
|
+
is_template_exists = model && (
|
44
|
+
['index', 'show'].include?(args.first) || # Everything has index and show
|
45
|
+
# Only CRU stuff has create / update / destroy
|
46
|
+
(!model.is_view? && ['new', 'create', 'edit', 'update', 'destroy'].include?(args.first))
|
47
|
+
)
|
29
48
|
)
|
30
|
-
|
31
|
-
|
49
|
+
instance_variable_set(:@_brick_model, model)
|
50
|
+
end
|
32
51
|
end
|
52
|
+
is_template_exists
|
33
53
|
end
|
34
|
-
is_template_exists
|
35
|
-
end
|
36
54
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
55
|
+
alias :_brick_find_template :find_template
|
56
|
+
def find_template(*args, **options)
|
57
|
+
if @_brick_model
|
58
|
+
model_name = @_brick_model.name
|
59
|
+
pk = @_brick_model.primary_key
|
60
|
+
obj_name = model_name.underscore
|
61
|
+
table_name = model_name.pluralize.underscore
|
62
|
+
# This gets has_many as well as has_many :through
|
63
|
+
# %%% weed out ones that don't have an available model to reference
|
64
|
+
bts, hms = @_brick_model.reflect_on_all_associations.each_with_object([{}, {}]) do |a, s|
|
65
|
+
case a.macro
|
66
|
+
when :belongs_to
|
67
|
+
# Build #brick_descrip if needed
|
68
|
+
unless a.klass.instance_methods(false).include?(:brick_descrip)
|
69
|
+
descrip_col = (a.klass.columns.map(&:name) - a.klass._brick_get_fks -
|
70
|
+
(::Brick.config.metadata_columns || []) -
|
71
|
+
[a.klass.primary_key]).first&.to_sym
|
72
|
+
if descrip_col
|
73
|
+
a.klass.define_method :brick_descrip do
|
74
|
+
send(descrip_col)
|
75
|
+
end
|
57
76
|
end
|
58
77
|
end
|
59
|
-
end
|
60
78
|
|
61
|
-
|
62
|
-
|
63
|
-
|
79
|
+
s.first[a.foreign_key] = [a.name, a.klass]
|
80
|
+
when :has_many
|
81
|
+
s.last[a.name] = a
|
82
|
+
end
|
83
|
+
s
|
64
84
|
end
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
85
|
+
# Weed out has_manys that go to an associative table
|
86
|
+
associatives = hms.select { |k, v| v.options[:through] }.each_with_object({}) do |hmt, s|
|
87
|
+
s[hmt.first] = hms.delete(hmt.last.options[:through]) # End up with a hash of HMT names pointing to join-table associations
|
88
|
+
end
|
89
|
+
hms_headers = hms.each_with_object(+'') { |hm, s| s << "<th>HM#{'T' if hm.last.options[:through]} #{hm.first}</th>\n" }
|
90
|
+
hms_columns = hms.each_with_object(+'') do |hm, s|
|
91
|
+
hm_fk_name = if hm.last.options[:through]
|
92
|
+
associative = associatives[hm.last.name]
|
93
|
+
"'#{associative.name}.#{associative.foreign_key}'"
|
94
|
+
else
|
95
|
+
hm.last.foreign_key
|
96
|
+
end
|
97
|
+
s << "<td>
|
98
|
+
<%= link_to \"#\{#{obj_name}.#{hm.first}.count\} #{hm.first}\", #{hm.last.klass.name.underscore.pluralize}_path({ #{hm_fk_name}: #{obj_name}.#{pk} }) %>
|
74
99
|
</td>\n"
|
75
|
-
|
100
|
+
end
|
76
101
|
|
77
|
-
|
78
|
-
|
79
|
-
|
102
|
+
inline = case args.first
|
103
|
+
when 'index'
|
104
|
+
"<p style=\"color: green\"><%= notice %></p>
|
80
105
|
|
81
106
|
<h1>#{model_name.pluralize}</h1>
|
82
107
|
<% if @_brick_params&.present? %><h3>where <%= @_brick_params.each_with_object([]) { |v, s| s << \"#\{v.first\} = #\{v.last.inspect\}\" }.join(', ') %></h3><% end %>
|
@@ -104,26 +129,26 @@ module Brick
|
|
104
129
|
<% if is_first # STILL haven't been able to write a first non-key / non-metadata column?
|
105
130
|
is_first = false
|
106
131
|
is_need_id_col = true %>
|
107
|
-
<
|
132
|
+
<th></th>
|
108
133
|
<% end %>
|
109
134
|
#{hms_headers}
|
110
135
|
</tr>
|
111
136
|
|
112
137
|
<% @#{table_name}.each do |#{obj_name}| %>
|
113
138
|
<tr>
|
114
|
-
<%
|
115
|
-
|
139
|
+
<% is_first = true
|
140
|
+
if is_need_id_col
|
141
|
+
is_first = false %>
|
142
|
+
<td><%= link_to \"#\{#{obj_name}.class.name\} ##\{#{obj_name}.id\}\", #{obj_name} %></td>
|
116
143
|
<% end %>
|
117
|
-
<%
|
144
|
+
<% #{obj_name}.attributes.each do |k, val| %>
|
118
145
|
<% next if k == '#{pk}' || ::Brick.config.metadata_columns.include?(k) %>
|
146
|
+
<td>
|
119
147
|
<% if (bt = bts[k]) %>
|
120
|
-
<td>
|
121
148
|
<%= obj = bt[1].find_by(bt.last => val); link_to obj.brick_descrip, obj %>
|
122
149
|
<% elsif is_first %>
|
123
|
-
<td>
|
124
150
|
<%= is_first = false; link_to val, #{obj_name} %>
|
125
151
|
<% else %>
|
126
|
-
<td>
|
127
152
|
<%= val %>
|
128
153
|
<% end %>
|
129
154
|
</td>
|
@@ -136,73 +161,64 @@ module Brick
|
|
136
161
|
|
137
162
|
<%= link_to \"New #{obj_name}\", new_#{obj_name}_path %>
|
138
163
|
"
|
139
|
-
|
140
|
-
|
141
|
-
|
164
|
+
# "<%= @#{@_brick_model.name.underscore.pluralize}.inspect %>"
|
165
|
+
when 'show'
|
166
|
+
"<%= @#{@_brick_model.name.underscore}.inspect %>"
|
167
|
+
end
|
168
|
+
# As if it were an inline template (see #determine_template in actionview-5.2.6.2/lib/action_view/renderer/template_renderer.rb)
|
169
|
+
keys = options.has_key?(:locals) ? options[:locals].keys : []
|
170
|
+
handler = ActionView::Template.handler_for_extension(options[:type] || 'erb')
|
171
|
+
ActionView::Template.new(inline, "auto-generated #{args.first} template", handler, locals: keys)
|
172
|
+
else
|
173
|
+
_brick_find_template(*args, **options)
|
142
174
|
end
|
143
|
-
puts inline
|
144
|
-
# As if it were an inline template (see #determine_template in actionview-5.2.6.2/lib/action_view/renderer/template_renderer.rb)
|
145
|
-
keys = options.has_key?(:locals) ? options[:locals].keys : []
|
146
|
-
handler = ActionView::Template.handler_for_extension(options[:type] || 'erb')
|
147
|
-
ActionView::Template.new(inline, "auto-generated #{args.first} template", handler, locals: keys)
|
148
|
-
else
|
149
|
-
_brick_find_template(*args, **options)
|
150
175
|
end
|
151
176
|
end
|
152
177
|
end
|
153
|
-
end
|
154
178
|
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
179
|
+
if ::Brick.enable_routes?
|
180
|
+
ActionDispatch::Routing::RouteSet.class_exec do
|
181
|
+
alias _brick_finalize_routeset! finalize!
|
182
|
+
def finalize!(*args, **options)
|
183
|
+
unless @finalized
|
184
|
+
existing_controllers = routes.each_with_object({}) { |r, s| c = r.defaults[:controller]; s[c] = nil if c }
|
185
|
+
::Rails.application.routes.append do
|
186
|
+
# %%% TODO: If no auto-controllers then enumerate the controllers folder in order to build matching routes
|
187
|
+
# If auto-controllers and auto-models are both enabled then this makes sense:
|
188
|
+
relations = (::Brick.instance_variable_get(:@relations) || {})[ActiveRecord::Base.connection_pool.object_id] || {}
|
189
|
+
relations.each do |k, v|
|
190
|
+
unless existing_controllers.key?(controller_name = k.underscore.pluralize)
|
191
|
+
options = {}
|
192
|
+
options[:only] = [:index, :show] if v.key?(:isView)
|
193
|
+
send(:resources, controller_name.to_sym, **options)
|
194
|
+
end
|
170
195
|
end
|
171
196
|
end
|
172
197
|
end
|
198
|
+
_brick_finalize_routeset!(*args, **options)
|
173
199
|
end
|
174
|
-
_brick_finalize_routeset!(*args, **options)
|
175
200
|
end
|
176
201
|
end
|
177
|
-
end
|
178
202
|
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
# Additional references (virtual foreign keys)
|
189
|
-
if (ars = (::Brick.additional_references = app.config.brick.fetch(:additional_references, nil)))
|
190
|
-
ars = ars.call if ars.is_a?(Proc)
|
191
|
-
ars = ars.to_a unless ars.is_a?(Array)
|
192
|
-
ars = [ars] unless ars.empty? || ars.first.is_a?(Array)
|
193
|
-
ars.each do |fk|
|
194
|
-
::Brick._add_bt_and_hm(fk[0..2])
|
203
|
+
# Additional references (virtual foreign keys)
|
204
|
+
if (ars = ::Brick.config.additional_references)
|
205
|
+
ars = ars.call if ars.is_a?(Proc)
|
206
|
+
ars = ars.to_a unless ars.is_a?(Array)
|
207
|
+
ars = [ars] unless ars.empty? || ars.first.is_a?(Array)
|
208
|
+
ars.each do |fk|
|
209
|
+
::Brick._add_bt_and_hm(fk[0..2])
|
210
|
+
end
|
195
211
|
end
|
196
|
-
end
|
197
212
|
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
213
|
+
# Find associative tables that can be set up for has_many :through
|
214
|
+
::Brick.relations.each do |_key, tbl|
|
215
|
+
tbl_cols = tbl[:cols].keys
|
216
|
+
fks = tbl[:fks].each_with_object({}) { |fk, s| s[fk.last[:fk]] = fk.last[:inverse_table] if fk.last[:is_bt]; s }
|
217
|
+
# Aside from the primary key and the metadata columns created_at, updated_at, and deleted_at, if this table only has
|
218
|
+
# foreign keys then it can act as an associative table and thus be used with has_many :through.
|
219
|
+
if fks.length > 1 && (tbl_cols - fks.keys - (::Brick.config.metadata_columns || []) - tbl[:pkey].values.first).length.zero?
|
220
|
+
fks.each { |fk| tbl[:hmt_fks][fk.first] = fk.last }
|
221
|
+
end
|
206
222
|
end
|
207
223
|
end
|
208
224
|
end
|
data/lib/brick/version_number.rb
CHANGED
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.3
|
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-03-
|
11
|
+
date: 2022-03-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|