brick 1.0.158 → 1.0.161
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/brick/compatibility.rb +7 -5
- data/lib/brick/extensions.rb +26 -6
- data/lib/brick/frameworks/rails/engine.rb +7 -83
- data/lib/brick/frameworks/rails/form_builder.rb +8 -3
- data/lib/brick/frameworks/rails/form_tags.rb +100 -1
- data/lib/brick/version_number.rb +1 -1
- data/lib/brick.rb +268 -259
- data/lib/generators/brick/migration_builder.rb +2 -0
- data/lib/generators/brick/migrations_generator.rb +0 -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: b6fde6ef1ff8f9e3d6787b53c64a881a88c448ce3adfc9ca5e6a25e8f815cc30
|
4
|
+
data.tar.gz: 2bcc9fe939bc4d879168032ff16aba60ceeb08854083b4f5912649b2eb056962
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8ebc0d8bc6765040e3df2a4b9debcec5d4326efd69d41e62188146c29f25bd254d381db651b4687fd6afe77d2f7ef5b6f640edde87fd7ddbd0c9b851bbabe74c
|
7
|
+
data.tar.gz: 97e7320e75a6f9589a8a96e751ad9c082826a4ae7698dcad2e487323075977f13bf2e2f8e2d889bf42d761f5649926b22d0e07e3e395456f9d04adc23fde064c
|
data/lib/brick/compatibility.rb
CHANGED
@@ -97,11 +97,13 @@ if Object.const_defined?('ActionPack') && !ActionPack.respond_to?(:version)
|
|
97
97
|
end
|
98
98
|
end
|
99
99
|
end
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
100
|
+
if Bundler.locked_gems&.dependencies.key?('action_view')
|
101
|
+
require 'action_view' # Needed for Rails <= 4.0
|
102
|
+
if Object.const_defined?('ActionView') && !ActionView.respond_to?(:version)
|
103
|
+
module ActionView
|
104
|
+
def self.version
|
105
|
+
ActionPack.version
|
106
|
+
end
|
105
107
|
end
|
106
108
|
end
|
107
109
|
end
|
data/lib/brick/extensions.rb
CHANGED
@@ -30,14 +30,14 @@
|
|
30
30
|
|
31
31
|
# Drag something like HierModel#name onto the rows and have it automatically add five columns -- where type=zone / where type = section / etc
|
32
32
|
|
33
|
-
# Support for Postgres / MySQL enums (add enum to model, use model enums to make a drop-down in the UI)
|
34
|
-
|
35
|
-
# Currently quadrupling up routes
|
36
|
-
|
37
33
|
# Modal pop-up things for editing large text / date ranges / hierarchies of data
|
38
34
|
|
39
35
|
# For recognised self-references, have the show page display all related objects up to the parent (or the start of a circular reference)
|
40
36
|
|
37
|
+
# When creating or updating an object through an auto-generated controller, it always goes to an auto-generated view template even if the user has supplied their own index.html.erb (or similar) view template
|
38
|
+
|
39
|
+
# Upon creation of a new object, when going to the index page, highlight this new object and scroll it into view (likely to the very bottom of everything, although might be sorted differently)
|
40
|
+
|
41
41
|
# ==========================================================
|
42
42
|
# Dynamically create model or controller classes when needed
|
43
43
|
# ==========================================================
|
@@ -972,9 +972,14 @@ JOIN (SELECT #{hm_selects.map { |s| _br_quoted_name("#{'br_t0.' if from_clause}#
|
|
972
972
|
(!a.options[:polymorphic] && a.klass == klass && klass_cols.include?(a.foreign_key))
|
973
973
|
)
|
974
974
|
end
|
975
|
+
|
975
976
|
# ActiveStorage compatibility
|
976
977
|
selects << 'service_name' if klass.name == 'ActiveStorage::Blob' && ActiveStorage::Blob.columns_hash.key?('service_name')
|
977
978
|
selects << 'blob_id' if klass.name == 'ActiveStorage::Attachment' && ActiveStorage::Attachment.columns_hash.key?('blob_id')
|
979
|
+
# Pay gem compatibility
|
980
|
+
selects << 'processor' if klass.name == 'Pay::Customer' && Pay::Customer.columns_hash.key?('processor')
|
981
|
+
selects << 'customer_id' if klass.name == 'Pay::Subscription' && Pay::Subscription.columns_hash.key?('customer_id')
|
982
|
+
|
978
983
|
pieces, my_dsl = klass.brick_parse_dsl(join_array = ::Brick::JoinArray.new, [], translations = {}, false, nil, true)
|
979
984
|
brick_select(
|
980
985
|
selects, where_values_hash, nil, translations: translations, join_array: join_array,
|
@@ -1131,6 +1136,20 @@ if Object.const_defined?('ActionView')
|
|
1131
1136
|
end
|
1132
1137
|
end
|
1133
1138
|
end
|
1139
|
+
|
1140
|
+
module ActionDispatch::Routing
|
1141
|
+
class Mapper
|
1142
|
+
module Base
|
1143
|
+
# Pro-actively assess Brick routes. Useful when there is a "catch all" wildcard route
|
1144
|
+
# at the end of an existing `routes.rb` file, which would normally steal the show and
|
1145
|
+
# not let Brick have any fun. So just call this right before any wildcard routes, and
|
1146
|
+
# you'll be in business!
|
1147
|
+
def mount_brick_routes
|
1148
|
+
add_brick_routes unless ::Brick.routes_done
|
1149
|
+
end
|
1150
|
+
end
|
1151
|
+
end
|
1152
|
+
end
|
1134
1153
|
end
|
1135
1154
|
|
1136
1155
|
if ActiveSupport::Dependencies.respond_to?(:autoload_module!) # %%% Only works with previous non-zeitwerk auto-loading
|
@@ -1807,7 +1826,7 @@ class Object
|
|
1807
1826
|
cspd.select! { |val| val == "'self'" }
|
1808
1827
|
cspd << style_value
|
1809
1828
|
else
|
1810
|
-
cspd << "'sha256-
|
1829
|
+
cspd << "'sha256-VbHigzrnU2KiWIjHStrKhnGxWRv25WXQNdKr5qhevD8='"
|
1811
1830
|
end
|
1812
1831
|
cspd << 'https://cdn.jsdelivr.net'
|
1813
1832
|
end
|
@@ -2199,7 +2218,8 @@ class Object
|
|
2199
2218
|
render json: { result: ::Brick.unexclude_column(table_name, col) }
|
2200
2219
|
else
|
2201
2220
|
@_lookup_context.instance_variable_set("@#{singular_table_name}".to_sym,
|
2202
|
-
model.send(:create, send(params_name_sym)))
|
2221
|
+
(created_obj = model.send(:create, send(params_name_sym))))
|
2222
|
+
# %%% Surface any errors to the user in a flash message
|
2203
2223
|
@_lookup_context.instance_variable_set(:@_brick_model, model)
|
2204
2224
|
index
|
2205
2225
|
render :index
|
@@ -1667,89 +1667,9 @@ end
|
|
1667
1667
|
end
|
1668
1668
|
%>
|
1669
1669
|
<br><br>
|
1670
|
-
|
1671
|
-
|
1672
|
-
|
1673
|
-
# If it's a new record, set any default polymorphic types
|
1674
|
-
bts.each do |_k, v|
|
1675
|
-
if v[2]
|
1676
|
-
@#{obj_name}.send(\"#\{model.brick_foreign_type(v.first)}=\", v[1].first&.first&.name)
|
1677
|
-
end
|
1678
|
-
end if @#{obj_name}.new_record?
|
1679
|
-
rtans = #{model_name}.rich_text_association_names if #{model_name}.respond_to?(:rich_text_association_names)
|
1680
|
-
(#{model_name}.column_names + (rtans || [])).each do |k|
|
1681
|
-
next if (#{(pk.map(&:to_s) || []).inspect}.include?(k) && !bts.key?(k)) ||
|
1682
|
-
::Brick.config.metadata_columns.include?(k)
|
1683
|
-
|
1684
|
-
col = #{model_name}.columns_hash[k]
|
1685
|
-
if !col && rtans&.include?(k)
|
1686
|
-
k = k[10..-1] if k.start_with?('rich_text_')
|
1687
|
-
col = (rt_col ||= ActiveRecord::ConnectionAdapters::Column.new(
|
1688
|
-
'', nil, ActiveRecord::ConnectionAdapters::SqlTypeMetadata.new(sql_type: 'varchar', type: :text)
|
1689
|
-
)
|
1690
|
-
)
|
1691
|
-
end
|
1692
|
-
val = @#{obj_name}.attributes[k] %>
|
1693
|
-
<tr>
|
1694
|
-
<th class=\"show-field\"<%= \" title=\\\"#\{col&.comment}\\\"\".html_safe if col&.respond_to?(:comment) && !col&.comment.blank? %>>
|
1695
|
-
<% has_fields = true
|
1696
|
-
if (bt = bts[k])
|
1697
|
-
# Add a final member in this array with descriptive options to be used in <select> drop-downs
|
1698
|
-
bt_name = bt[1].map { |x| x.first.name }.join('/')
|
1699
|
-
# %%% Only do this if the user has permissions to edit this bt field
|
1700
|
-
if bt[2] # Polymorphic?
|
1701
|
-
poly_class_name = orig_poly_name = @#{obj_name}.send(model.brick_foreign_type(bt.first))
|
1702
|
-
bt_pair = nil
|
1703
|
-
loop do
|
1704
|
-
bt_pair = bt[1].find { |pair| pair.first.name == poly_class_name }
|
1705
|
-
# Accommodate any valid STI by going up the chain of inheritance
|
1706
|
-
break unless bt_pair.nil? && poly_class_name = ::Brick.existing_stis[poly_class_name]
|
1707
|
-
end
|
1708
|
-
puts \"*** Might be missing an STI class called #\{orig_poly_name\} whose base class should have this:
|
1709
|
-
*** has_many :#{table_name}, as: :#\{bt.first\}
|
1710
|
-
*** Can probably auto-configure everything using these lines in an initialiser:
|
1711
|
-
*** Brick.sti_namespace_prefixes = { '::#\{orig_poly_name\}' => 'SomeParentModel' }
|
1712
|
-
*** Brick.polymorphics = { '#{table_name}.#\{bt.first\}' => ['SomeParentModel'] }\" if bt_pair.nil?
|
1713
|
-
# descrips = @_brick_bt_descrip[bt.first][bt_class]
|
1714
|
-
poly_id = @#{obj_name}.send(\"#\{bt.first\}_id\")
|
1715
|
-
# bt_class.order(obj_pk = bt_class.primary_key).each { |obj| option_detail << [obj.brick_descrip(nil, obj_pk), obj.send(obj_pk)] }
|
1716
|
-
end
|
1717
|
-
bt_pair ||= bt[1].first # If there's no polymorphism (or polymorphism status is unknown), just get the first one
|
1718
|
-
bt_class = bt_pair&.first
|
1719
|
-
if bt.length < 4
|
1720
|
-
bt << (option_detail = [[\"(No #\{bt_name\} chosen)\", '^^^brick_NULL^^^']])
|
1721
|
-
# %%% Accommodate composite keys for obj.pk at the end here
|
1722
|
-
collection, descrip_cols = bt_class&.order(Arel.sql(\"#\{bt_class.table_name}.#\{obj_pk = bt_class.primary_key}\"))&.brick_list
|
1723
|
-
collection&.brick_(:each) do |obj|
|
1724
|
-
option_detail << [
|
1725
|
-
obj.brick_descrip(
|
1726
|
-
descrip_cols&.first&.map { |col2| obj.send(col2.last) },
|
1727
|
-
obj_pk
|
1728
|
-
), obj.send(obj_pk)
|
1729
|
-
]
|
1730
|
-
end
|
1731
|
-
end %>
|
1732
|
-
BT <%= bt_class&.bt_link(bt.first) || orig_poly_name %>
|
1733
|
-
<% else %>
|
1734
|
-
<%= #{model_name}.human_attribute_name(k, { default: k }) %>
|
1735
|
-
<% end %>
|
1736
|
-
</th>
|
1737
|
-
<td>
|
1738
|
-
<%= f.brick_field(k, html_options = {}, val, col, bt, bt_class, bt_name, bt_pair) %>
|
1739
|
-
</td>
|
1740
|
-
</tr>
|
1741
|
-
<% end
|
1742
|
-
if has_fields %>
|
1743
|
-
<tr><td colspan=\"2\"><%= f.submit({ class: 'update' }) %></td></tr>
|
1744
|
-
<% else %>
|
1745
|
-
<tr><td colspan=\"2\">(No displayable fields)</td></tr>
|
1746
|
-
<% end %>
|
1747
|
-
</table>#{
|
1748
|
-
"<%= begin
|
1749
|
-
::Brick::Rails.display_binary(obj&.blob&.download, 500_000)&.html_safe
|
1750
|
-
rescue
|
1751
|
-
end %>" if model_name == 'ActiveStorage::Attachment'}
|
1752
|
-
<% end %>
|
1670
|
+
|
1671
|
+
<%= # Write out the mega-form
|
1672
|
+
brick_form_for(obj, options, #{model_name}, bts, #{pk.inspect}) %>
|
1753
1673
|
|
1754
1674
|
#{unless args.first == 'new'
|
1755
1675
|
# Was: confirm_are_you_sure = ActionView.version < ::Gem::Version.new('7.0') ? "data: { confirm: 'Delete #\{model_name} -- Are you sure?' }" : "form: { data: { turbo_confirm: 'Delete #\{model_name} -- Are you sure?' } }"
|
@@ -2064,6 +1984,10 @@ document.querySelectorAll(\"input, select\").forEach(function (inp) {
|
|
2064
1984
|
# In order to defer auto-creation of any routes that already exist, calculate Brick routes only after having loaded all others
|
2065
1985
|
prepend ::Brick::RouteSet
|
2066
1986
|
end
|
1987
|
+
ActionDispatch::Routing::Mapper.class_exec do
|
1988
|
+
include ::Brick::RouteMapper
|
1989
|
+
end
|
1990
|
+
|
2067
1991
|
# Do the root route before the Rails Welcome one would otherwise take precedence
|
2068
1992
|
if (route = ::Brick.config.default_route_fallback).present?
|
2069
1993
|
action = "#{route}#{'#index' unless route.index('#')}"
|
@@ -67,9 +67,14 @@ module Brick::Rails::FormBuilder
|
|
67
67
|
when :boolean
|
68
68
|
out << self.check_box(method.to_sym)
|
69
69
|
when :integer, :decimal, :float
|
70
|
-
|
71
|
-
|
72
|
-
|
70
|
+
if model.respond_to?(:attribute_types) && (enum_type = model.attribute_types[method]).is_a?(ActiveRecord::Enum::EnumType)
|
71
|
+
opts = enum_type.send(:mapping)&.each_with_object([]) { |v, s| s << [v.first, v.first] } || []
|
72
|
+
out << self.select(method.to_sym, [["(No #{method} chosen)", '^^^brick_NULL^^^']] + opts, { value: val || '^^^brick_NULL^^^' }, options)
|
73
|
+
else
|
74
|
+
digit_pattern = col_type == :integer ? '\d*' : '\d*(?:\.\d*|)'
|
75
|
+
# Used to do this for float / decimal: self.number_field method.to_sym
|
76
|
+
out << self.text_field(method.to_sym, { pattern: digit_pattern, class: 'check-validity' })
|
77
|
+
end
|
73
78
|
when *DT_PICKERS.keys
|
74
79
|
template.instance_variable_set(:@_date_fields_present, true)
|
75
80
|
out << self.text_field(method.to_sym, { class: DT_PICKERS[col_type] })
|
@@ -203,6 +203,101 @@ module Brick::Rails::FormTags
|
|
203
203
|
out.html_safe
|
204
204
|
end # brick_grid
|
205
205
|
|
206
|
+
# Our mega show/new/update form
|
207
|
+
def brick_form_for(obj, options = {}, model = obj.class, bts = {}, pk = (obj.class.primary_key || []))
|
208
|
+
pk = [pk] unless pk.is_a?(Array)
|
209
|
+
pk.map!(&:to_s)
|
210
|
+
form_for(obj.becomes(model), options) do |f|
|
211
|
+
out = +'<table class="shadow">'
|
212
|
+
has_fields = false
|
213
|
+
# If it's a new record, set any default polymorphic types
|
214
|
+
bts&.each do |_k, v|
|
215
|
+
if v[2]
|
216
|
+
obj.send("#{model.brick_foreign_type(v.first)}=", v[1].first&.first&.name)
|
217
|
+
end
|
218
|
+
end if obj.new_record?
|
219
|
+
rtans = model.rich_text_association_names if model.respond_to?(:rich_text_association_names)
|
220
|
+
(model.column_names + (rtans || [])).each do |k|
|
221
|
+
next if (pk.include?(k) && !bts.key?(k)) ||
|
222
|
+
::Brick.config.metadata_columns.include?(k)
|
223
|
+
|
224
|
+
col = model.columns_hash[k]
|
225
|
+
if !col && rtans&.include?(k)
|
226
|
+
k = k[10..-1] if k.start_with?('rich_text_')
|
227
|
+
col = (rt_col ||= ActiveRecord::ConnectionAdapters::Column.new(
|
228
|
+
'', nil, ActiveRecord::ConnectionAdapters::SqlTypeMetadata.new(sql_type: 'varchar', type: :text)
|
229
|
+
)
|
230
|
+
)
|
231
|
+
end
|
232
|
+
val = obj.attributes[k]
|
233
|
+
out << "
|
234
|
+
<tr>
|
235
|
+
<th class=\"show-field\"#{" title=\"#{col&.comment}\"".html_safe if col&.respond_to?(:comment) && !col&.comment.blank?}>"
|
236
|
+
has_fields = true
|
237
|
+
if (bt = bts[k])
|
238
|
+
# Add a final member in this array with descriptive options to be used in <select> drop-downs
|
239
|
+
bt_name = bt[1].map { |x| x.first.name }.join('/')
|
240
|
+
# %%% Only do this if the user has permissions to edit this bt field
|
241
|
+
if bt[2] # Polymorphic?
|
242
|
+
poly_class_name = orig_poly_name = obj.send(model.brick_foreign_type(bt.first))
|
243
|
+
bt_pair = nil
|
244
|
+
loop do
|
245
|
+
bt_pair = bt[1].find { |pair| pair.first.name == poly_class_name }
|
246
|
+
# Accommodate any valid STI by going up the chain of inheritance
|
247
|
+
break unless bt_pair.nil? && poly_class_name = ::Brick.existing_stis[poly_class_name]
|
248
|
+
end
|
249
|
+
table_name = model.name.split('::').last.underscore.pluralize
|
250
|
+
puts "*** Might be missing an STI class called #{orig_poly_name} whose base class should have this:
|
251
|
+
*** has_many :#{table_name}, as: :#{bt.first}
|
252
|
+
*** Can probably auto-configure everything using these lines in an initialiser:
|
253
|
+
*** Brick.sti_namespace_prefixes = { '::#{orig_poly_name}' => 'SomeParentModel' }
|
254
|
+
*** Brick.polymorphics = { '#{table_name}.#{bt.first}' => ['SomeParentModel'] }" if bt_pair.nil?
|
255
|
+
# descrips = @_brick_bt_descrip[bt.first][bt_class]
|
256
|
+
poly_id = obj.send("#{bt.first}_id")
|
257
|
+
# bt_class.order(obj_pk = bt_class.primary_key).each { |obj| option_detail << [obj.brick_descrip(nil, obj_pk), obj.send(obj_pk)] }
|
258
|
+
end
|
259
|
+
bt_pair ||= bt[1].first # If there's no polymorphism (or polymorphism status is unknown), just get the first one
|
260
|
+
bt_class = bt_pair&.first
|
261
|
+
if bt.length < 4
|
262
|
+
bt << (option_detail = [["(No #{bt_name} chosen)", '^^^brick_NULL^^^']])
|
263
|
+
# %%% Accommodate composite keys for obj.pk at the end here
|
264
|
+
collection, descrip_cols = bt_class&.order(Arel.sql("#{bt_class.table_name}.#{obj_pk = bt_class.primary_key}"))&.brick_list
|
265
|
+
collection&.brick_(:each) do |obj|
|
266
|
+
option_detail << [
|
267
|
+
obj.brick_descrip(
|
268
|
+
descrip_cols&.first&.map { |col2| obj.send(col2.last) },
|
269
|
+
obj_pk
|
270
|
+
), obj.send(obj_pk)
|
271
|
+
]
|
272
|
+
end
|
273
|
+
end
|
274
|
+
out << "BT #{bt_class&.bt_link(bt.first) || orig_poly_name}"
|
275
|
+
else
|
276
|
+
out << model.human_attribute_name(k, { default: k })
|
277
|
+
end
|
278
|
+
out << "
|
279
|
+
</th>
|
280
|
+
<td>
|
281
|
+
#{f.brick_field(k, html_options = {}, val, col, bt, bt_class, bt_name, bt_pair)}
|
282
|
+
</td>
|
283
|
+
</tr>"
|
284
|
+
end
|
285
|
+
if has_fields
|
286
|
+
out << "<tr><td colspan=\"2\">#{f.submit({ class: 'update' })}</td></tr>"
|
287
|
+
else
|
288
|
+
out << '<tr><td colspan="2">(No displayable fields)</td></tr>'
|
289
|
+
end
|
290
|
+
out << '</table>'
|
291
|
+
if model.name == 'ActiveStorage::Attachment'
|
292
|
+
begin
|
293
|
+
out << ::Brick::Rails.display_binary(obj&.blob&.download, 500_000)&.html_safe
|
294
|
+
rescue
|
295
|
+
end
|
296
|
+
end
|
297
|
+
out.html_safe
|
298
|
+
end
|
299
|
+
end # brick_form_for
|
300
|
+
|
206
301
|
def link_to_brick(*args, **kwargs)
|
207
302
|
return unless ::Brick.config.mode == :on
|
208
303
|
|
@@ -291,7 +386,11 @@ module Brick::Rails::FormTags
|
|
291
386
|
if (links = _brick_resource_from_iv(true)).length == 1 # If there's only one match then use any text that was supplied
|
292
387
|
link_to_brick(text || links.first.last.join('/'), links.first.first, **kwargs)
|
293
388
|
else
|
294
|
-
links.each_with_object([])
|
389
|
+
links.each_with_object([]) do |v, s|
|
390
|
+
if (link = link_to_brick(v.join('/'), v, **kwargs))
|
391
|
+
s << link
|
392
|
+
end
|
393
|
+
end.join(' ').html_safe
|
295
394
|
end
|
296
395
|
end
|
297
396
|
end # link_to_brick
|
data/lib/brick/version_number.rb
CHANGED
data/lib/brick.rb
CHANGED
@@ -794,296 +794,303 @@ In config/initializers/brick.rb appropriate entries would look something like:
|
|
794
794
|
|
795
795
|
module RouteSet
|
796
796
|
def finalize!
|
797
|
-
|
798
|
-
return super if self != routeset_to_use || ::Brick.routes_done
|
797
|
+
return super if self != ::Rails.application.routes || ::Brick.routes_done
|
799
798
|
|
799
|
+
append do
|
800
|
+
add_brick_routes
|
801
|
+
end
|
802
|
+
super
|
803
|
+
end
|
804
|
+
end
|
805
|
+
|
806
|
+
module RouteMapper
|
807
|
+
def add_brick_routes
|
808
|
+
routeset_to_use = ::Rails.application.routes
|
800
809
|
path_prefix = ::Brick.config.path_prefix
|
801
|
-
existing_controllers = routes.each_with_object({}) do |r, s|
|
810
|
+
existing_controllers = routeset_to_use.routes.each_with_object({}) do |r, s|
|
802
811
|
c = r.defaults[:controller]
|
803
812
|
s[c] = nil if c
|
804
813
|
end
|
805
|
-
|
806
|
-
|
807
|
-
|
808
|
-
|
809
|
-
|
810
|
-
|
811
|
-
|
812
|
-
|
813
|
-
|
814
|
-
|
815
|
-
|
816
|
-
end
|
817
|
-
send(:scope, { module: module_name || path_name, path: path_name, as: path_name }) do
|
818
|
-
brick_namespace_create.call(path_names, res_name, options)
|
819
|
-
end
|
820
|
-
else
|
821
|
-
send(:resources, res_name.to_sym, **options)
|
814
|
+
|
815
|
+
tables = []
|
816
|
+
views = []
|
817
|
+
table_class_length = 38 # Length of "Classes that can be built from tables:"
|
818
|
+
view_class_length = 37 # Length of "Classes that can be built from views:"
|
819
|
+
|
820
|
+
brick_namespace_create = lambda do |path_names, res_name, options|
|
821
|
+
if path_names&.present?
|
822
|
+
if (path_name = path_names.pop).is_a?(Array)
|
823
|
+
module_name = path_name[1]
|
824
|
+
path_name = path_name.first
|
822
825
|
end
|
826
|
+
send(:scope, { module: module_name || path_name, path: path_name, as: path_name }) do
|
827
|
+
brick_namespace_create.call(path_names, res_name, options)
|
828
|
+
end
|
829
|
+
else
|
830
|
+
send(:resources, res_name.to_sym, **options)
|
823
831
|
end
|
832
|
+
end
|
824
833
|
|
825
|
-
|
826
|
-
|
827
|
-
|
828
|
-
|
829
|
-
|
830
|
-
|
831
|
-
|
832
|
-
|
833
|
-
|
834
|
-
|
835
|
-
|
836
|
-
|
834
|
+
# %%% TODO: If no auto-controllers then enumerate the controllers folder in order to build matching routes
|
835
|
+
# If auto-controllers and auto-models are both enabled then this makes sense:
|
836
|
+
controller_prefix = (path_prefix ? "#{path_prefix}/" : '')
|
837
|
+
sti_subclasses = ::Brick.config.sti_namespace_prefixes.each_with_object(Hash.new { |h, k| h[k] = [] }) do |v, s|
|
838
|
+
# Turn something like {"::Spouse"=>"Person", "::Friend"=>"Person"} into {"Person"=>["Spouse", "Friend"]}
|
839
|
+
s[v.last] << v.first[2..-1] unless v.first.end_with?('::')
|
840
|
+
end
|
841
|
+
versioned_views = {} # Track which views have already been done for each api_root
|
842
|
+
::Brick.relations.each do |k, v|
|
843
|
+
if (schema_name = v.fetch(:schema, nil))
|
844
|
+
schema_prefix = "#{schema_name}."
|
845
|
+
end
|
837
846
|
|
838
|
-
|
839
|
-
|
840
|
-
|
841
|
-
|
842
|
-
|
843
|
-
object_name = k.split('.').last # Take off any first schema part
|
844
|
-
|
845
|
-
full_schema_prefix = if (aps = v.fetch(:auto_prefixed_schema, nil))
|
846
|
-
aps = aps[0..-2] if aps[-1] == '_'
|
847
|
-
(schema_prefix&.dup || +'') << "#{aps}."
|
848
|
-
else
|
849
|
-
schema_prefix
|
850
|
-
end
|
851
|
-
|
852
|
-
# Track routes being built
|
853
|
-
if (class_name = v.fetch(:class_name, nil))
|
854
|
-
if v.key?(:isView)
|
855
|
-
view_class_length = class_name.length if class_name.length > view_class_length
|
856
|
-
views
|
857
|
-
else
|
858
|
-
table_class_length = class_name.length if class_name.length > table_class_length
|
859
|
-
tables
|
860
|
-
end << [class_name, aps, resource_name]
|
861
|
-
end
|
847
|
+
next if !(resource_name = v.fetch(:resource, nil)) ||
|
848
|
+
existing_controllers.key?(
|
849
|
+
controller_prefix + (resource_name = "#{schema_prefix&.tr('.', '/')}#{resource_name}".pluralize)
|
850
|
+
)
|
862
851
|
|
863
|
-
|
864
|
-
options[:only] = [:index, :show] if v.key?(:isView)
|
865
|
-
|
866
|
-
# First do the normal routes
|
867
|
-
prefixes = []
|
868
|
-
prefixes << [aps, v[:class_name]&.split('::')[-2]&.underscore] if aps
|
869
|
-
prefixes << schema_name if schema_name
|
870
|
-
prefixes << path_prefix if path_prefix
|
871
|
-
brick_namespace_create.call(prefixes, v[:resource], options)
|
872
|
-
sti_subclasses.fetch(class_name, nil)&.each do |sc| # Add any STI subclass routes for this relation
|
873
|
-
brick_namespace_create.call(prefixes, sc.underscore.tr('/', '_').pluralize, options)
|
874
|
-
end
|
852
|
+
object_name = k.split('.').last # Take off any first schema part
|
875
853
|
|
876
|
-
|
877
|
-
|
878
|
-
|
879
|
-
|
880
|
-
|
881
|
-
|
882
|
-
|
883
|
-
|
884
|
-
|
885
|
-
|
886
|
-
|
887
|
-
|
888
|
-
|
889
|
-
|
890
|
-
|
891
|
-
|
892
|
-
|
893
|
-
|
894
|
-
|
895
|
-
|
896
|
-
|
897
|
-
|
898
|
-
|
899
|
-
|
900
|
-
|
901
|
-
|
902
|
-
|
903
|
-
|
904
|
-
|
905
|
-
|
906
|
-
|
907
|
-
|
908
|
-
|
909
|
-
|
910
|
-
|
911
|
-
|
912
|
-
|
913
|
-
|
914
|
-
|
915
|
-
|
916
|
-
|
917
|
-
|
854
|
+
full_schema_prefix = if (aps = v.fetch(:auto_prefixed_schema, nil))
|
855
|
+
aps = aps[0..-2] if aps[-1] == '_'
|
856
|
+
(schema_prefix&.dup || +'') << "#{aps}."
|
857
|
+
else
|
858
|
+
schema_prefix
|
859
|
+
end
|
860
|
+
|
861
|
+
# Track routes being built
|
862
|
+
if (class_name = v.fetch(:class_name, nil))
|
863
|
+
if v.key?(:isView)
|
864
|
+
view_class_length = class_name.length if class_name.length > view_class_length
|
865
|
+
views
|
866
|
+
else
|
867
|
+
table_class_length = class_name.length if class_name.length > table_class_length
|
868
|
+
tables
|
869
|
+
end << [class_name, aps, resource_name]
|
870
|
+
end
|
871
|
+
|
872
|
+
options = {}
|
873
|
+
options[:only] = [:index, :show] if v.key?(:isView)
|
874
|
+
|
875
|
+
# First do the normal routes
|
876
|
+
prefixes = []
|
877
|
+
prefixes << [aps, v[:class_name]&.split('::')[-2]&.underscore] if aps
|
878
|
+
prefixes << schema_name if schema_name
|
879
|
+
prefixes << path_prefix if path_prefix
|
880
|
+
brick_namespace_create.call(prefixes, v[:resource], options)
|
881
|
+
sti_subclasses.fetch(class_name, nil)&.each do |sc| # Add any STI subclass routes for this relation
|
882
|
+
brick_namespace_create.call(prefixes, sc.underscore.tr('/', '_').pluralize, options)
|
883
|
+
end
|
884
|
+
|
885
|
+
# Now the API routes if necessary
|
886
|
+
full_resource = nil
|
887
|
+
::Brick.api_roots&.each do |api_root|
|
888
|
+
api_done_views = (versioned_views[api_root] ||= {})
|
889
|
+
found = nil
|
890
|
+
test_ver_num = nil
|
891
|
+
view_relation = nil
|
892
|
+
# If it's a view then see if there's a versioned one available by searching for resource names
|
893
|
+
# versioned with the closest number (equal to or less than) compared with our API version number.
|
894
|
+
if v.key?(:isView)
|
895
|
+
if (ver = object_name.match(/^v([\d_]*)/)&.captures&.first) && ver[-1] == '_'
|
896
|
+
core_object_name = object_name[ver.length + 1..-1]
|
897
|
+
next if api_done_views.key?(unversioned = "#{schema_prefix}v_#{core_object_name}")
|
898
|
+
|
899
|
+
# Expect that the last item in the path generally holds versioning information
|
900
|
+
api_ver = api_root.split('/')[-1]&.gsub('_', '.')
|
901
|
+
vn_idx = api_ver.rindex(/[^\d._]/) # Position of the first numeric digit at the end of the version number
|
902
|
+
# Was: .to_d
|
903
|
+
test_ver_num = api_ver_num = api_ver[vn_idx + 1..-1].gsub('_', '.').to_i # Attempt to turn something like "v3" into the decimal value 3
|
904
|
+
# puts [api_ver, vn_idx, api_ver_num, unversioned].inspect
|
905
|
+
|
906
|
+
next if ver.to_i > api_ver_num # Don't surface any newer views in an older API
|
907
|
+
|
908
|
+
test_ver_num -= 1 until test_ver_num.zero? ||
|
909
|
+
(view_relation = ::Brick.relations.fetch(
|
910
|
+
found = "#{schema_prefix}v#{test_ver_num}_#{core_object_name}", nil
|
911
|
+
))
|
912
|
+
api_done_views[unversioned] = nil # Mark that for this API version this view is done
|
913
|
+
|
914
|
+
# puts "Found #{found}" if view_relation
|
915
|
+
# If we haven't found "v3_view_name" or "v2_view_name" or so forth, at the last
|
916
|
+
# fall back to simply looking for "v_view_name", and then finally "view_name".
|
917
|
+
no_v_prefix_name = "#{schema_prefix}#{core_object_name}"
|
918
|
+
standard_prefix = 'v_'
|
918
919
|
else
|
919
|
-
|
920
|
+
core_object_name = object_name
|
921
|
+
end
|
922
|
+
if (rvp = ::Brick.config.api_remove_view_prefix) && core_object_name.start_with?(rvp)
|
923
|
+
core_object_name.slice!(0, rvp.length)
|
920
924
|
end
|
925
|
+
no_prefix_name = "#{schema_prefix}#{core_object_name}"
|
926
|
+
unversioned = "#{schema_prefix}#{standard_prefix}#{::Brick.config.api_add_view_prefix}#{core_object_name}"
|
927
|
+
else
|
928
|
+
unversioned = k
|
929
|
+
end
|
921
930
|
|
922
|
-
|
923
|
-
|
924
|
-
|
925
|
-
|
926
|
-
|
927
|
-
|
928
|
-
|
929
|
-
|
930
|
-
|
931
|
-
|
932
|
-
|
933
|
-
|
934
|
-
|
935
|
-
|
936
|
-
|
937
|
-
end
|
931
|
+
view_relation ||= ::Brick.relations.fetch(found = unversioned, nil) ||
|
932
|
+
(no_v_prefix_name && ::Brick.relations.fetch(found = no_v_prefix_name, nil)) ||
|
933
|
+
(no_prefix_name && ::Brick.relations.fetch(found = no_prefix_name, nil))
|
934
|
+
if view_relation
|
935
|
+
actions = view_relation.key?(:isView) ? [:index, :show] : ::Brick::ALL_API_ACTIONS # By default all actions are allowed
|
936
|
+
# Call proc that limits which endpoints get surfaced based on version, table or view name, method (get list / get one / post / patch / delete)
|
937
|
+
# Returning nil makes it do nothing, false makes it skip creating this endpoint, and an array of up to
|
938
|
+
# these 3 things controls and changes the nature of the endpoint that gets built:
|
939
|
+
# (updated api_name, name of different relation to route to, allowed actions such as :index, :show, :create, etc)
|
940
|
+
proc_result = if (filter = ::Brick.config.api_filter).is_a?(Proc)
|
941
|
+
begin
|
942
|
+
num_args = filter.arity.negative? ? 6 : filter.arity
|
943
|
+
filter.call(*[unversioned, k, view_relation, actions, api_ver_num, found, test_ver_num][0...num_args])
|
944
|
+
rescue StandardError => e
|
945
|
+
puts "::Brick.api_filter Proc error: #{e.message}"
|
938
946
|
end
|
939
|
-
|
947
|
+
end
|
948
|
+
# proc_result expects to receive back: [updated_api_name, to_other_relation, allowed_actions]
|
940
949
|
|
941
|
-
|
942
|
-
|
943
|
-
|
944
|
-
|
945
|
-
|
946
|
-
|
947
|
-
|
948
|
-
|
949
|
-
|
950
|
-
end
|
951
|
-
# Otherwise don't change this array because it's probably legit
|
952
|
-
when String
|
953
|
-
proc_result = [proc_result] # Treat this as the surfaced api_name (path) they want to use for this endpoint
|
954
|
-
else
|
955
|
-
puts "::Brick.api_filter Proc warning: Unable to parse this result returned: \n #{proc_result.inspect}"
|
956
|
-
proc_result = nil # Couldn't understand what in the world was returned
|
950
|
+
case proc_result
|
951
|
+
when NilClass
|
952
|
+
# Do nothing differently than what normal behaviour would be
|
953
|
+
when FalseClass # Skip implementing this endpoint
|
954
|
+
view_relation[:api][api_ver_num] = nil
|
955
|
+
next
|
956
|
+
when Array # Did they give back an array of actions?
|
957
|
+
unless proc_result.any? { |pr| ::Brick::ALL_API_ACTIONS.exclude?(pr) }
|
958
|
+
proc_result = [unversioned, to_relation, proc_result]
|
957
959
|
end
|
960
|
+
# Otherwise don't change this array because it's probably legit
|
961
|
+
when String
|
962
|
+
proc_result = [proc_result] # Treat this as the surfaced api_name (path) they want to use for this endpoint
|
963
|
+
else
|
964
|
+
puts "::Brick.api_filter Proc warning: Unable to parse this result returned: \n #{proc_result.inspect}"
|
965
|
+
proc_result = nil # Couldn't understand what in the world was returned
|
966
|
+
end
|
958
967
|
|
959
|
-
|
960
|
-
|
961
|
-
|
962
|
-
|
963
|
-
|
964
|
-
|
965
|
-
|
966
|
-
end
|
967
|
-
end
|
968
|
-
if proc_result.first&.!=(k) # updated_api_name -- a different name than this relation would normally have
|
969
|
-
found = proc_result.first
|
968
|
+
if proc_result&.present?
|
969
|
+
if proc_result[1] # to_other_relation
|
970
|
+
if (new_view_relation = ::Brick.relations.fetch(proc_result[1], nil))
|
971
|
+
k = proc_result[1] # Route this call over to this different relation
|
972
|
+
view_relation = new_view_relation
|
973
|
+
else
|
974
|
+
puts "::Brick.api_filter Proc warning: Unable to find new suggested relation with name #{proc_result[1]} -- sticking with #{k} instead."
|
970
975
|
end
|
971
|
-
actions &= proc_result[2] if proc_result[2] # allowed_actions
|
972
976
|
end
|
973
|
-
(
|
974
|
-
|
975
|
-
# view_ver_num = if (first_part = k.split('_').first) =~ /^v[\d_]+/
|
976
|
-
# first_part[1..-1].gsub('_', '.').to_i
|
977
|
-
# end
|
978
|
-
controller_name = if (last = view_relation.fetch(:resource, nil)&.pluralize)
|
979
|
-
"#{full_schema_prefix}#{last}"
|
980
|
-
else
|
981
|
-
found
|
982
|
-
end.tr('.', '/')
|
983
|
-
|
984
|
-
{ :index => 'get', :create => 'post' }.each do |action, method|
|
985
|
-
if actions.include?(action)
|
986
|
-
# Normally goes to something like: /api/v1/employees
|
987
|
-
send(method, "#{api_root}#{unversioned.tr('.', '/')}", { to: "#{controller_prefix}#{controller_name}##{action}" })
|
988
|
-
end
|
977
|
+
if proc_result.first&.!=(k) # updated_api_name -- a different name than this relation would normally have
|
978
|
+
found = proc_result.first
|
989
979
|
end
|
990
|
-
|
991
|
-
|
992
|
-
|
993
|
-
|
994
|
-
|
995
|
-
|
996
|
-
|
980
|
+
actions &= proc_result[2] if proc_result[2] # allowed_actions
|
981
|
+
end
|
982
|
+
(view_relation[:api][api_ver_num] ||= {})[unversioned] = actions # Add to the list of API paths this resource responds to
|
983
|
+
|
984
|
+
# view_ver_num = if (first_part = k.split('_').first) =~ /^v[\d_]+/
|
985
|
+
# first_part[1..-1].gsub('_', '.').to_i
|
986
|
+
# end
|
987
|
+
controller_name = if (last = view_relation.fetch(:resource, nil)&.pluralize)
|
988
|
+
"#{full_schema_prefix}#{last}"
|
989
|
+
else
|
990
|
+
found
|
991
|
+
end.tr('.', '/')
|
992
|
+
|
993
|
+
{ :index => 'get', :create => 'post' }.each do |action, method|
|
994
|
+
if actions.include?(action)
|
995
|
+
# Normally goes to something like: /api/v1/employees
|
996
|
+
send(method, "#{api_root}#{unversioned.tr('.', '/')}", { to: "#{controller_prefix}#{controller_name}##{action}" })
|
997
|
+
end
|
998
|
+
end
|
999
|
+
# %%% We do not yet surface the #show action
|
1000
|
+
if (id_col = view_relation[:pk]&.first) # ID-dependent stuff
|
1001
|
+
{ :update => ['put', 'patch'], :destroy => ['delete'] }.each do |action, methods|
|
1002
|
+
if actions.include?(action)
|
1003
|
+
methods.each do |method|
|
1004
|
+
send(method, "#{api_root}#{unversioned.tr('.', '/')}/:#{id_col}", { to: "#{controller_prefix}#{controller_name}##{action}" })
|
997
1005
|
end
|
998
1006
|
end
|
999
1007
|
end
|
1000
1008
|
end
|
1001
1009
|
end
|
1010
|
+
end
|
1002
1011
|
|
1003
|
-
|
1004
|
-
|
1005
|
-
|
1006
|
-
|
1007
|
-
|
1008
|
-
|
1009
|
-
end
|
1010
|
-
rescue
|
1012
|
+
# Trestle compatibility
|
1013
|
+
if Object.const_defined?('Trestle') && ::Trestle.config.options&.key?(:site_title) &&
|
1014
|
+
!Object.const_defined?("#{(res_name = resource_name.tr('/', '_')).camelize}Admin")
|
1015
|
+
begin
|
1016
|
+
::Trestle.resource(res_sym = res_name.to_sym, model: class_name&.constantize) do
|
1017
|
+
menu { item res_sym, icon: "fa fa-star" }
|
1011
1018
|
end
|
1019
|
+
rescue
|
1012
1020
|
end
|
1013
1021
|
end
|
1022
|
+
end
|
1014
1023
|
|
1015
|
-
|
1016
|
-
|
1017
|
-
|
1018
|
-
|
1019
|
-
|
1020
|
-
|
1021
|
-
|
1022
|
-
end
|
1023
|
-
|
1024
|
-
if ::Brick.config.add_orphans && (orphans_as = "#{controller_prefix.tr('/', '_')}brick_orphans".to_sym)
|
1025
|
-
(
|
1026
|
-
!(orphans_route = instance_variable_get(:@set).named_routes.find { |route| route.first == orphans_as }&.last) ||
|
1027
|
-
!orphans_route.ast.to_s.include?("/#{controller_prefix}brick_orphans/")
|
1028
|
-
)
|
1029
|
-
get("/#{controller_prefix}brick_orphans", to: 'brick_gem#orphans', as: 'brick_orphans')
|
1030
|
-
end
|
1024
|
+
if (named_routes = instance_variable_get(:@set).named_routes).respond_to?(:find)
|
1025
|
+
if ::Brick.config.add_status && (status_as = "#{controller_prefix.tr('/', '_')}brick_status".to_sym)
|
1026
|
+
(
|
1027
|
+
!(status_route = instance_variable_get(:@set).named_routes.find { |route| route.first == status_as }&.last) ||
|
1028
|
+
!status_route.ast.to_s.include?("/#{controller_prefix}brick_status/")
|
1029
|
+
)
|
1030
|
+
get("/#{controller_prefix}brick_status", to: 'brick_gem#status', as: status_as.to_s)
|
1031
1031
|
end
|
1032
1032
|
|
1033
|
-
if
|
1034
|
-
|
1035
|
-
|
1033
|
+
if ::Brick.config.add_orphans && (orphans_as = "#{controller_prefix.tr('/', '_')}brick_orphans".to_sym)
|
1034
|
+
(
|
1035
|
+
!(orphans_route = instance_variable_get(:@set).named_routes.find { |route| route.first == orphans_as }&.last) ||
|
1036
|
+
!orphans_route.ast.to_s.include?("/#{controller_prefix}brick_orphans/")
|
1037
|
+
)
|
1038
|
+
get("/#{controller_prefix}brick_orphans", to: 'brick_gem#orphans', as: 'brick_orphans')
|
1036
1039
|
end
|
1040
|
+
end
|
1037
1041
|
|
1038
|
-
|
1039
|
-
|
1040
|
-
|
1041
|
-
|
1042
|
-
|
1043
|
-
|
1044
|
-
|
1045
|
-
|
1046
|
-
|
1042
|
+
if instance_variable_get(:@set).named_routes.names.exclude?(:brick_crosstab)
|
1043
|
+
get("/#{controller_prefix}brick_crosstab", to: 'brick_gem#crosstab', as: 'brick_crosstab')
|
1044
|
+
get("/#{controller_prefix}brick_crosstab/data", to: 'brick_gem#crosstab_data')
|
1045
|
+
end
|
1046
|
+
|
1047
|
+
if Object.const_defined?('Rswag::Ui')
|
1048
|
+
rswag_path = routeset_to_use.routes.find { |r| r.app.app == Rswag::Ui::Engine }&.instance_variable_get(:@path_formatter)&.instance_variable_get(:@parts)&.join
|
1049
|
+
first_endpoint_parts = nil
|
1050
|
+
(doc_endpoints = Rswag::Ui.config.config_object[:urls])&.each do |doc_endpoint|
|
1051
|
+
puts "Mounting OpenApi 3.0 documentation endpoint for \"#{doc_endpoint[:name]}\" on #{doc_endpoint[:url]}" unless ::Brick.routes_done
|
1052
|
+
send(:get, doc_endpoint[:url], { to: 'brick_openapi#index' })
|
1053
|
+
endpoint_parts = doc_endpoint[:url]&.split('/')
|
1054
|
+
first_endpoint_parts ||= endpoint_parts
|
1047
1055
|
end
|
1048
|
-
|
1056
|
+
end
|
1057
|
+
return if ::Brick.routes_done
|
1049
1058
|
|
1050
|
-
|
1051
|
-
|
1052
|
-
|
1053
|
-
|
1054
|
-
else
|
1055
|
-
puts "In order to make documentation available you can put this into your routes.rb:"
|
1056
|
-
puts " mount Rswag::Ui::Engine => '/#{first_endpoint_parts&.find(&:present?) || 'api-docs'}'"
|
1057
|
-
end
|
1059
|
+
if Object.const_defined?('Rswag::Ui')
|
1060
|
+
if doc_endpoints.present?
|
1061
|
+
if rswag_path && first_endpoint_parts
|
1062
|
+
puts "API documentation now available when navigating to: /#{first_endpoint_parts&.find(&:present?)}/index.html"
|
1058
1063
|
else
|
1059
|
-
|
1064
|
+
puts "In order to make documentation available you can put this into your routes.rb:"
|
1065
|
+
puts " mount Rswag::Ui::Engine => '/#{first_endpoint_parts&.find(&:present?) || 'api-docs'}'"
|
1066
|
+
end
|
1067
|
+
else
|
1068
|
+
sample_path = rswag_path || '/api-docs'
|
1069
|
+
puts
|
1070
|
+
puts "Brick: rswag-ui gem detected -- to make OpenAPI 3.0 documentation available from a path such as '#{sample_path}/v1/swagger.json',"
|
1071
|
+
puts ' put code such as this in an initializer:'
|
1072
|
+
puts ' Rswag::Ui.configure do |config|'
|
1073
|
+
puts " config.swagger_endpoint '#{sample_path}/v1/swagger.json', 'API V1 Docs'"
|
1074
|
+
puts ' end'
|
1075
|
+
unless rswag_path
|
1060
1076
|
puts
|
1061
|
-
puts
|
1062
|
-
puts
|
1063
|
-
puts ' Rswag::Ui.configure do |config|'
|
1064
|
-
puts " config.swagger_endpoint '#{sample_path}/v1/swagger.json', 'API V1 Docs'"
|
1065
|
-
puts ' end'
|
1066
|
-
unless rswag_path
|
1067
|
-
puts
|
1068
|
-
puts ' and put this into your routes.rb:'
|
1069
|
-
puts " mount Rswag::Ui::Engine => '/api-docs'"
|
1070
|
-
end
|
1077
|
+
puts ' and put this into your routes.rb:'
|
1078
|
+
puts " mount Rswag::Ui::Engine => '/api-docs'"
|
1071
1079
|
end
|
1072
1080
|
end
|
1081
|
+
end
|
1073
1082
|
|
1074
|
-
|
1075
|
-
|
1076
|
-
|
1077
|
-
|
1078
|
-
|
1079
|
-
|
1080
|
-
|
1081
|
-
|
1082
|
-
|
1083
|
-
|
1084
|
-
end
|
1083
|
+
puts "\n" if tables.present? || views.present?
|
1084
|
+
if tables.present?
|
1085
|
+
puts "Classes that can be built from tables:#{' ' * (table_class_length - 38)} Path:"
|
1086
|
+
puts "======================================#{' ' * (table_class_length - 38)} ====="
|
1087
|
+
::Brick.display_classes(controller_prefix, tables, table_class_length)
|
1088
|
+
end
|
1089
|
+
if views.present?
|
1090
|
+
puts "Classes that can be built from views:#{' ' * (view_class_length - 37)} Path:"
|
1091
|
+
puts "=====================================#{' ' * (view_class_length - 37)} ====="
|
1092
|
+
::Brick.display_classes(controller_prefix, views, view_class_length)
|
1085
1093
|
end
|
1086
|
-
super
|
1087
1094
|
::Brick.routes_done = true
|
1088
1095
|
end
|
1089
1096
|
end
|
@@ -1112,20 +1119,22 @@ require 'active_record/relation'
|
|
1112
1119
|
require 'active_record/relation/query_methods' if ActiveRecord.version < ::Gem::Version.new('5')
|
1113
1120
|
require 'rails/railtie' if ActiveRecord.version < ::Gem::Version.new('4.2')
|
1114
1121
|
|
1115
|
-
|
1116
|
-
|
1117
|
-
|
1118
|
-
|
1122
|
+
if Object.const_defined?('Rails')
|
1123
|
+
# Rake tasks
|
1124
|
+
class Railtie < ::Rails::Railtie
|
1125
|
+
Dir.glob("#{File.expand_path(__dir__)}/brick/tasks/**/*.rake").each { |task| load task }
|
1126
|
+
end
|
1119
1127
|
|
1120
|
-
# Rails < 4.2 does not have env
|
1121
|
-
module ::Rails
|
1122
|
-
|
1123
|
-
|
1124
|
-
|
1125
|
-
|
1128
|
+
# Rails < 4.2 does not have env
|
1129
|
+
module ::Rails
|
1130
|
+
unless respond_to?(:env)
|
1131
|
+
def self.env
|
1132
|
+
@_env ||= ActiveSupport::StringInquirer.new(ENV["RAILS_ENV"] || ENV["RACK_ENV"] || "development")
|
1133
|
+
end
|
1126
1134
|
|
1127
|
-
|
1128
|
-
|
1135
|
+
def self.env=(environment)
|
1136
|
+
@_env = ActiveSupport::StringInquirer.new(environment)
|
1137
|
+
end
|
1129
1138
|
end
|
1130
1139
|
end
|
1131
1140
|
end
|
@@ -8,7 +8,6 @@ require 'generators/brick/migration_builder'
|
|
8
8
|
module Brick
|
9
9
|
# Auto-generates migration files
|
10
10
|
class MigrationsGenerator < ::Rails::Generators::Base
|
11
|
-
include FancyGets
|
12
11
|
include ::Brick::MigrationBuilder
|
13
12
|
|
14
13
|
desc 'Auto-generates migration files for an existing database.'
|
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.161
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lorin Thwaits
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-08-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|