brick 1.0.158 → 1.0.161
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/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
|