brick 1.0.204 → 1.0.205

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9bf1dd73cdb0040884c92622e0a7dab4c36232440b5f70e74c2f9f362843373d
4
- data.tar.gz: 19fd7bbfd6088ed1606b6c2a5ad2fa67cb9dd3b6217313bdfaa368b4fc1ca5f0
3
+ metadata.gz: 3abdf25aeb401676febcc1ea98ce104a9e005ecae652f17daf3736baab63d5ea
4
+ data.tar.gz: 195eb8e27607f719808954914a409b356c249384cacd0535fab65652b02cd4ec
5
5
  SHA512:
6
- metadata.gz: eb16cd17c3ad18718164242957e71353ccb5708650136a44517a13255b65d40dc47d6b579defd92d76b9b6a77c696a386880db70f6c2d1495a0f198f64866dbc
7
- data.tar.gz: 97e22cd5f88a8008313362558ccb5ab7829772568573f0622e2eba61640d5a59ae44135d4870878f90bd750d496ed8aeef0e22badffe4168b142580911650b11
6
+ metadata.gz: 187b1740a3f0e54f061c9b293df233c32993eb00ca4a218e1b32b7888c8b72c4fb9d2889ec7a2a469f95d3b39242b9adc8c02167c76065a5dcfd45262714793c
7
+ data.tar.gz: 132fecbea3bcf8783a0ad2ca540747af4a74e882d0fdba60bf0491c0ee19e52e9ef378d6a39ab3df89cbac3bcd6dee760959f969f45e17587b6a0b643f9e1bb3
data/lib/brick/config.rb CHANGED
@@ -234,7 +234,7 @@ module Brick
234
234
 
235
235
  # Polymorphic associations
236
236
  def polymorphics
237
- @mutex.synchronize { @polymorphics }
237
+ @mutex.synchronize { @polymorphics ||= {} }
238
238
  end
239
239
 
240
240
  def polymorphics=(polys)
@@ -344,7 +344,7 @@ module Brick
344
344
  end
345
345
 
346
346
  def table_name_prefixes
347
- @mutex.synchronize { @table_name_prefixes }
347
+ @mutex.synchronize { @table_name_prefixes ||= {} }
348
348
  end
349
349
 
350
350
  def table_name_prefixes=(value)
@@ -384,7 +384,7 @@ module Brick
384
384
  end
385
385
 
386
386
  def metadata_columns
387
- @mutex.synchronize { @metadata_columns }
387
+ @mutex.synchronize { @metadata_columns ||= ['created_at', 'updated_at', 'deleted_at'] }
388
388
  end
389
389
 
390
390
  def metadata_columns=(columns)
@@ -1175,34 +1175,6 @@ Might want to add this in your brick.rb:
1175
1175
  end
1176
1176
  end
1177
1177
 
1178
- if ::Brick.enable_routes? && Object.const_defined?('ActionDispatch')
1179
- require 'brick/route_mapper'
1180
- ActionDispatch::Routing::RouteSet.class_exec do
1181
- # In order to defer auto-creation of any routes that already exist, calculate Brick routes only after having loaded all others
1182
- prepend ::Brick::RouteSet
1183
- end
1184
- ActionDispatch::Routing::Mapper.class_exec do
1185
- include ::Brick::RouteMapper
1186
- end
1187
-
1188
- # Do the root route before the Rails Welcome one would otherwise take precedence
1189
- if (route = ::Brick.config.default_route_fallback).present?
1190
- action = "#{route}#{'#index' unless route.index('#')}"
1191
- if ::Brick.config.path_prefix
1192
- ::Rails.application.routes.append do
1193
- send(:namespace, ::Brick.config.path_prefix) do
1194
- send(:root, action)
1195
- end
1196
- end
1197
- elsif ::Rails.application.routes.named_routes.send(:routes)[:root].nil?
1198
- ::Rails.application.routes.append do
1199
- send(:root, action)
1200
- end
1201
- end
1202
- ::Brick.established_drf = "/#{::Brick.config.path_prefix}#{action[action.index('#')..-1]}"
1203
- end
1204
- end
1205
-
1206
1178
  if Object.const_defined?('ActionView')
1207
1179
  require 'brick/frameworks/rails/form_tags'
1208
1180
  require 'brick/frameworks/rails/form_builder'
@@ -1800,6 +1772,18 @@ class Object
1800
1772
  new_model_class.send(:has_many, hmt_name.to_sym, **options)
1801
1773
  end
1802
1774
  end
1775
+
1776
+ # Auto-support Ransack if it's present
1777
+ if self.respond_to?(:ransackable_attributes)
1778
+ def self.ransackable_attributes(auth_object = nil)
1779
+ column_names + _ransackers.keys
1780
+ end
1781
+
1782
+ def self.ransackable_associations(auth_object = nil)
1783
+ reflect_on_all_associations.map { |a| a.name.to_s } + _ransackers.keys
1784
+ end
1785
+ end
1786
+
1803
1787
  code << "end # model #{full_name}\n"
1804
1788
  end # model class definition
1805
1789
  [built_model, code]
@@ -209,51 +209,95 @@ function linkSchemas() {
209
209
  # paths['app/models'] << 'lib/brick/frameworks/active_record/models'
210
210
  config.brick = ActiveSupport::OrderedOptions.new
211
211
  ActiveSupport.on_load(:before_initialize) do |app|
212
- if ::Rails.application.respond_to?(:reloader)
213
- ::Rails.application.reloader.to_prepare { Module.class_exec &::Brick::ADD_CONST_MISSING }
214
- else # For Rails < 5.0, just load it once at the start
215
- Module.class_exec &::Brick::ADD_CONST_MISSING
212
+
213
+ # --------------------------------------------
214
+ # 1. Load three initializers early
215
+ # (inflectsions.rb, brick.rb, apartment.rb)
216
+ # Very first thing, load inflections since we'll be using .pluralize and .singularize on table and model names
217
+ if File.exist?(inflections = ::Rails.root&.join('config/initializers/inflections.rb') || '')
218
+ load inflections
216
219
  end
217
220
  require 'brick/join_array'
218
- is_development = (ENV['RAILS_ENV'] || ENV['RACK_ENV']) == 'development'
219
- ::Brick.enable_models = app.config.brick.fetch(:enable_models, true)
220
- ::Brick.enable_controllers = app.config.brick.fetch(:enable_controllers, is_development)
221
- ::Brick.enable_views = app.config.brick.fetch(:enable_views, is_development)
222
- ::Brick.enable_routes = app.config.brick.fetch(:enable_routes, is_development)
223
- ::Brick.skip_database_views = app.config.brick.fetch(:skip_database_views, false)
224
-
225
- # Specific database tables and views to omit when auto-creating models
226
- ::Brick.exclude_tables = app.config.brick.fetch(:exclude_tables, [])
227
-
228
- # When table names have specific prefixes, automatically place them in their own module with a table_name_prefix.
229
- ::Brick.config.table_name_prefixes ||= app.config.brick.fetch(:table_name_prefixes, {})
230
-
231
- # Columns to treat as being metadata for purposes of identifying associative tables for has_many :through
232
- ::Brick.metadata_columns = app.config.brick.fetch(:metadata_columns, ['created_at', 'updated_at', 'deleted_at'])
233
-
234
- # Columns for which to add a validate presence: true even though the database doesn't have them marked as NOT NULL
235
- ::Brick.not_nullables = app.config.brick.fetch(:not_nullables, [])
236
-
237
- # Additional references (virtual foreign keys)
238
- ::Brick.additional_references = app.config.brick.fetch(:additional_references, nil)
239
-
240
- # Custom columns to add to a table, minimally defined with a name and DSL string
241
- ::Brick.custom_columns = app.config.brick.fetch(:custom_columns, nil)
242
-
243
- # When table names have specific prefixes, automatically place them in their own module with a table_name_prefix.
244
- ::Brick.order = app.config.brick.fetch(:order, {})
221
+ # Now the Brick initializer since there may be important schema things configured
222
+ if !::Brick.initializer_loaded && File.exist?(brick_initializer = ::Rails.root&.join('config/initializers/brick.rb') || '')
223
+ ::Brick.initializer_loaded = load brick_initializer
224
+
225
+ # After loading the initializer, add compatibility for ActiveStorage and ActionText if those haven't already been
226
+ # defined. (Further JSON configuration for ActiveStorage metadata happens later in the after_initialize hook.)
227
+ # begin
228
+ ['ActiveStorage', 'ActionText'].each do |ar_extension|
229
+ if Object.const_defined?(ar_extension) &&
230
+ (extension = Object.const_get(ar_extension)).respond_to?(:table_name_prefix) &&
231
+ !::Brick.config.table_name_prefixes.key?(as_tnp = extension.table_name_prefix)
232
+ ::Brick.config.table_name_prefixes[as_tnp] = ar_extension
233
+ end
234
+ end
235
+ # rescue # NoMethodError
236
+ # end
245
237
 
246
- # Skip creating a has_many association for these
247
- ::Brick.exclude_hms = app.config.brick.fetch(:exclude_hms, nil)
238
+ # Support the followability gem: https://github.com/nejdetkadir/followability
239
+ if Object.const_defined?('Followability') && !::Brick.config.table_name_prefixes.key?('followability_')
240
+ ::Brick.config.table_name_prefixes['followability_'] = 'Followability'
241
+ end
242
+ end
243
+ # Load the initializer for the Apartment gem a little early so that if .excluded_models and
244
+ # .default_schema are specified then we can work with non-tenanted models more appropriately
245
+ if (apartment = Object.const_defined?('Apartment')) &&
246
+ File.exist?(apartment_initializer = ::Rails.root.join('config/initializers/apartment.rb'))
247
+ require 'apartment/adapters/abstract_adapter'
248
+ Apartment::Adapters::AbstractAdapter.class_exec do
249
+ if instance_methods.include?(:process_excluded_models)
250
+ def process_excluded_models
251
+ # All other models will share a connection (at Apartment.connection_class) and we can modify at will
252
+ Apartment.excluded_models.each do |excluded_model|
253
+ begin
254
+ process_excluded_model(excluded_model)
255
+ rescue NameError => e
256
+ (@bad_models ||= []) << excluded_model
257
+ end
258
+ end
259
+ end
260
+ end
261
+ end
262
+ unless @_apartment_loaded
263
+ load apartment_initializer
264
+ @_apartment_loaded = true
265
+ end
266
+ end
248
267
 
249
- # Has one relationships
250
- ::Brick.has_ones = app.config.brick.fetch(:has_ones, nil)
268
+ if ::Brick.enable_routes? && Object.const_defined?('ActionDispatch')
269
+ require 'brick/route_mapper'
270
+ ActionDispatch::Routing::RouteSet.class_exec do
271
+ # In order to defer auto-creation of any routes that already exist, calculate Brick routes only after having loaded all others
272
+ prepend ::Brick::RouteSet
273
+ end
274
+ ActionDispatch::Routing::Mapper.class_exec do
275
+ include ::Brick::RouteMapper
276
+ end
251
277
 
252
- # accepts_nested_attributes_for relationships
253
- ::Brick.nested_attributes = app.config.brick.fetch(:nested_attributes, nil)
278
+ # Do the root route before the Rails Welcome one would otherwise take precedence
279
+ if (route = ::Brick.config.default_route_fallback).present?
280
+ action = "#{route}#{'#index' unless route.index('#')}"
281
+ if ::Brick.config.path_prefix
282
+ ::Rails.application.routes.append do
283
+ send(:namespace, ::Brick.config.path_prefix) do
284
+ send(:root, action)
285
+ end
286
+ end
287
+ elsif ::Rails.application.routes.named_routes.send(:routes)[:root].nil?
288
+ ::Rails.application.routes.append do
289
+ send(:root, action)
290
+ end
291
+ end
292
+ ::Brick.established_drf = "/#{::Brick.config.path_prefix}#{action[action.index('#')..-1]}"
293
+ end
294
+ end
254
295
 
255
- # Polymorphic associations
256
- ::Brick.polymorphics = app.config.brick.fetch(:polymorphics, nil)
296
+ if ::Rails.application.respond_to?(:reloader)
297
+ ::Rails.application.reloader.to_prepare { Module.class_exec &::Brick::ADD_CONST_MISSING }
298
+ else # For Rails < 5.0, just load it once at the start
299
+ Module.class_exec &::Brick::ADD_CONST_MISSING
300
+ end
257
301
  end
258
302
 
259
303
  # After we're initialized and before running the rest of stuff, put our configuration in place
@@ -497,20 +541,43 @@ window.addEventListener(\"popstate\", linkSchemas);
497
541
  end
498
542
  end
499
543
  end
500
- ::ActiveAdmin::Views::TitleBar.class_exec do
501
- alias _brick_build_title_tag build_title_tag
502
- def build_title_tag
503
- if klass = begin
504
- aa_id = helpers.instance_variable_get(:@current_tab)&.id
505
- ::Brick.relations.fetch(aa_id, nil)&.fetch(:class_name, nil)&.constantize
506
- rescue
507
- end
508
- h2((@title + link_to_brick(nil,
509
- BRICK_SVG.html_safe, # This would do well to be sized a bit smaller
510
- { title: "#{@_name} in Brick" }
511
- )).html_safe)
512
- else
513
- _brick_build_title_tag # Revert to the original
544
+ if (aav = ::ActiveAdmin::Views).const_defined?('TitleBar') # ActiveAdmin < 4.0
545
+ aav::TitleBar.class_exec do
546
+ alias _brick_build_title_tag build_title_tag
547
+ def build_title_tag
548
+ if klass = begin
549
+ aa_id = helpers.instance_variable_get(:@current_tab)&.id
550
+ ::Brick.relations.fetch(aa_id, nil)&.fetch(:class_name, nil)&.constantize
551
+ rescue
552
+ end
553
+ h2((@title + link_to_brick(nil,
554
+ BRICK_SVG.html_safe, # This would do well to be sized a bit smaller
555
+ { title: "#{@_name} in Brick" }
556
+ )).html_safe)
557
+ else
558
+ _brick_build_title_tag # Revert to the original
559
+ end
560
+ end
561
+ end
562
+ else # ActiveAdmin 4.0 or later
563
+ is_aa_4x = true
564
+ ::ActiveAdmin::ResourceController.class_exec do
565
+ include ActionView::Helpers::UrlHelper
566
+ include ::Brick::Rails::FormTags
567
+ alias _brick_default_page_title default_page_title
568
+ def default_page_title
569
+ dpt = _brick_default_page_title
570
+ if klass = begin
571
+ ::Brick.relations.fetch(@current_menu_item&.id, nil)&.fetch(:class_name, nil)&.constantize
572
+ rescue
573
+ end
574
+ (dpt + link_to_brick(nil,
575
+ BRICK_SVG.html_safe,
576
+ { title: "#{dpt} in Brick" }
577
+ )).html_safe
578
+ else
579
+ dpt
580
+ end
514
581
  end
515
582
  end
516
583
  end
@@ -523,9 +590,8 @@ window.addEventListener(\"popstate\", linkSchemas);
523
590
  div class: "blank_slate_container", id: "dashboard_default_message" do
524
591
  span class: "blank_slate" do
525
592
  span I18n.t("active_admin.dashboard_welcome.welcome")
526
- small I18n.t("active_admin.dashboard_welcome.call_to_action")
527
593
  end
528
- end
594
+ end unless is_aa_4x
529
595
  end
530
596
  end
531
597
  end
@@ -1402,7 +1468,7 @@ end %>#{"
1402
1468
  end
1403
1469
  \"<tr><td colspan=\\\"#\{td_count}\\\">Children: #\{child_links.join(' ')}</tr>\".html_safe
1404
1470
  end
1405
- %><%= if (page_num = @#{res_name = table_name.pluralize}._brick_page_num)
1471
+ %><%= if (page_num = @#{res_name = table_name.pluralize}&._brick_page_num)
1406
1472
  \"<tr><td colspan=\\\"#\{td_count}\\\">Page #\{page_num}</td></tr>\".html_safe
1407
1473
  end %></table>#{template_link}<%
1408
1474
  if description.present? %><span class=\"__brick\"><%=
@@ -1790,11 +1856,12 @@ flatpickr(\".timepicker\", {enableTime: true, noCalendar: true});
1790
1856
  <link rel=\"stylesheet\" type=\"text/css\" href=\"https://cdn.jsdelivr.net/npm/trix@2.0/dist/trix.min.css\">
1791
1857
  <% end %>
1792
1858
 
1793
- <% # Started with v0.14.4 of vanilla-jsoneditor
1859
+ <% # Good up until v0.19.0, and then with v0.20.0 of vanilla-jsoneditor started to get:
1860
+ # Uncaught TypeError: Failed to resolve module specifier \"immutable-json-patch\". Relative references must start with either \"/\", \"./\", or \"../\".
1794
1861
  if @_json_fields_present %>
1795
- <link rel=\"stylesheet\" type=\"text/css\" href=\"https://cdn.jsdelivr.net/npm/vanilla-jsoneditor/themes/jse-theme-default.min.css\">
1862
+ <link rel=\"stylesheet\" type=\"text/css\" href=\"https://cdn.jsdelivr.net/npm/vanilla-jsoneditor@0.19.0/themes/jse-theme-default.min.css\">
1796
1863
  <script type=\"module\">
1797
- import { JSONEditor } from \"https://cdn.jsdelivr.net/npm/vanilla-jsoneditor/index.min.js\";
1864
+ import { JSONEditor } from \"https://cdn.jsdelivr.net/npm/vanilla-jsoneditor@0.19.0/index.min.js\";
1798
1865
  document.querySelectorAll(\"input.jsonpicker\").forEach(function (inp) {
1799
1866
  var jsonDiv;
1800
1867
  if (jsonDiv = document.getElementById(\"_br_json_\" + inp.id)) {
@@ -69,8 +69,8 @@ module Brick::Rails::FormTags
69
69
 
70
70
  if show_aa_button != false && Object.const_defined?('ActiveAdmin')
71
71
  ActiveAdmin.application.namespaces.names.each do |ns|
72
- out << "
73
- <td>#{link_to_brick(
72
+ out << "
73
+ <td>#{link_to_brick(
74
74
  ::Brick::Rails::AA_PNG.html_safe,
75
75
  { index_proc: Proc.new do |aa_model, relation|
76
76
  path_helper = "#{ns}_#{relation.fetch(:auto_prefixed_schema, nil)}#{aa_model.model_name.route_key}_path".to_sym
@@ -31,61 +31,8 @@ module Brick
31
31
 
32
32
  orig_schema = nil
33
33
  if (relations = ::Brick.relations).keys == [:db_name]
34
- ::Brick.remove_instance_variable(:@_additional_references_loaded) if ::Brick.instance_variable_defined?(:@_additional_references_loaded)
34
+ # ::Brick.remove_instance_variable(:@_additional_references_loaded) if ::Brick.instance_variable_defined?(:@_additional_references_loaded)
35
35
 
36
- # --------------------------------------------
37
- # 1. Load three initializers early
38
- # (inflectsions.rb, brick.rb, apartment.rb)
39
- # Very first thing, load inflections since we'll be using .pluralize and .singularize on table and model names
40
- if File.exist?(inflections = ::Rails.root&.join('config/initializers/inflections.rb') || '')
41
- load inflections
42
- end
43
- # Now the Brick initializer since there may be important schema things configured
44
- if !::Brick.initializer_loaded && File.exist?(brick_initializer = ::Rails.root&.join('config/initializers/brick.rb') || '')
45
- ::Brick.initializer_loaded = load brick_initializer
46
-
47
- # After loading the initializer, add compatibility for ActiveStorage and ActionText if those haven't already been
48
- # defined. (Further JSON configuration for ActiveStorage metadata happens later in the after_initialize hook.)
49
- # begin
50
- ['ActiveStorage', 'ActionText'].each do |ar_extension|
51
- if Object.const_defined?(ar_extension) &&
52
- (extension = Object.const_get(ar_extension)).respond_to?(:table_name_prefix) &&
53
- !::Brick.config.table_name_prefixes.key?(as_tnp = extension.table_name_prefix)
54
- ::Brick.config.table_name_prefixes[as_tnp] = ar_extension
55
- end
56
- end
57
- # rescue # NoMethodError
58
- # end
59
-
60
- # Support the followability gem: https://github.com/nejdetkadir/followability
61
- if Object.const_defined?('Followability') && !::Brick.config.table_name_prefixes.key?('followability_')
62
- ::Brick.config.table_name_prefixes['followability_'] = 'Followability'
63
- end
64
- end
65
- # Load the initializer for the Apartment gem a little early so that if .excluded_models and
66
- # .default_schema are specified then we can work with non-tenanted models more appropriately
67
- if (apartment = Object.const_defined?('Apartment')) &&
68
- File.exist?(apartment_initializer = ::Rails.root.join('config/initializers/apartment.rb'))
69
- require 'apartment/adapters/abstract_adapter'
70
- Apartment::Adapters::AbstractAdapter.class_exec do
71
- if instance_methods.include?(:process_excluded_models)
72
- def process_excluded_models
73
- # All other models will share a connection (at Apartment.connection_class) and we can modify at will
74
- Apartment.excluded_models.each do |excluded_model|
75
- begin
76
- process_excluded_model(excluded_model)
77
- rescue NameError => e
78
- (@bad_models ||= []) << excluded_model
79
- end
80
- end
81
- end
82
- end
83
- end
84
- unless @_apartment_loaded
85
- load apartment_initializer
86
- @_apartment_loaded = true
87
- end
88
- end
89
36
  # Only for Postgres (Doesn't work in sqlite3 or MySQL)
90
37
  # puts ActiveRecord::Base.execute_sql("SELECT current_setting('SEARCH_PATH')").to_a.inspect
91
38
 
@@ -438,7 +385,7 @@ ORDER BY 1, 2, c.internal_column_id, acc.position"
438
385
  loop do
439
386
  klass = Object
440
387
  proposed_name_parts.each do |part|
441
- if klass.const_defined?(part)
388
+ if klass.const_defined?(part) && klass.name != part
442
389
  begin
443
390
  klass = klass.const_get(part)
444
391
  rescue NoMethodError => e
@@ -5,7 +5,7 @@ module Brick
5
5
  module VERSION
6
6
  MAJOR = 1
7
7
  MINOR = 0
8
- TINY = 204
8
+ TINY = 205
9
9
 
10
10
  # PRE is nil unless it's a pre-release (beta, RC, etc.)
11
11
  PRE = nil
data/lib/brick.rb CHANGED
@@ -232,10 +232,6 @@ module Brick
232
232
  )
233
233
  )
234
234
  )
235
- # unless a.polymorphic? || (!a.belongs_to? && (through = a.options[:through])) ||
236
- # (a.klass && ::Brick.config.exclude_tables.exclude?(a.klass.table_name) &&
237
- # (!a.belongs_to? || (same_type = (fk_type = model_cols[a.foreign_key.to_s]&.type) == pk_type))
238
- # )
239
235
  if same_type == false # We really do want to test specifically for false here, and not nil!
240
236
  puts "WARNING:
241
237
  Foreign key column #{a.klass.table_name}.#{a.foreign_key} is #{fk_type}, but the primary key it relates to, #{primary_klass.table_name}.#{a_pk}, is #{pk_type}.
@@ -171,7 +171,7 @@ if ActiveRecord::Base.respond_to?(:brick_select) && !::Brick.initializer_loaded
171
171
 
172
172
  # # Custom path prefix to apply to all auto-generated Brick routes. Also causes auto-generated controllers
173
173
  # # to be created inside a module with the same name.
174
- # ::Brick.path_prefix = 'admin'
174
+ # ::Brick.path_prefix = 'brick'
175
175
 
176
176
  # # Normally all are enabled in development mode, and for security reasons only models are enabled in production
177
177
  # # and test. This allows you to either (a) turn off models entirely, or (b) enable controllers, views, and routes
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.204
4
+ version: 1.0.205
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lorin Thwaits
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-02-11 00:00:00.000000000 Z
11
+ date: 2024-02-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -285,7 +285,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
285
285
  - !ruby/object:Gem::Version
286
286
  version: 1.3.6
287
287
  requirements: []
288
- rubygems_version: 3.2.33
288
+ rubygems_version: 3.1.6
289
289
  signing_key:
290
290
  specification_version: 4
291
291
  summary: Create a Rails app from data alone