action_blocks 0.1.0

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.
Files changed (69) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +21 -0
  3. data/README.md +121 -0
  4. data/Rakefile +33 -0
  5. data/app/assets/config/action_blocks.js +2 -0
  6. data/app/assets/javascripts/action_blocks/application.js +15 -0
  7. data/app/assets/stylesheets/action_blocks/application.css +15 -0
  8. data/app/controllers/action_blocks/attachments_controller.rb +22 -0
  9. data/app/controllers/action_blocks/barchart_blocks_controller.rb +14 -0
  10. data/app/controllers/action_blocks/base_controller.rb +22 -0
  11. data/app/controllers/action_blocks/blocks_controller.rb +16 -0
  12. data/app/controllers/action_blocks/command_blocks_controller.rb +6 -0
  13. data/app/controllers/action_blocks/form_blocks_controller.rb +13 -0
  14. data/app/controllers/action_blocks/model_blocks_controller.rb +13 -0
  15. data/app/controllers/action_blocks/table_blocks_controller.rb +13 -0
  16. data/app/controllers/action_blocks/workspace_blocks_controller.rb +6 -0
  17. data/app/helpers/action_blocks/application_helper.rb +4 -0
  18. data/app/jobs/action_blocks/application_job.rb +4 -0
  19. data/app/mailers/action_blocks/application_mailer.rb +6 -0
  20. data/app/models/action_blocks/application_record.rb +5 -0
  21. data/app/views/layouts/action_blocks/application.html.erb +16 -0
  22. data/config/initializers/action_blocks.rb +9 -0
  23. data/config/routes.rb +10 -0
  24. data/lib/action_block_loader.rb +120 -0
  25. data/lib/action_blocks.rb +76 -0
  26. data/lib/action_blocks/builders/authorization_builder.rb +21 -0
  27. data/lib/action_blocks/builders/barchart_builder.rb +48 -0
  28. data/lib/action_blocks/builders/base_builder.rb +221 -0
  29. data/lib/action_blocks/builders/block_type.rb +11 -0
  30. data/lib/action_blocks/builders/command_builder.rb +6 -0
  31. data/lib/action_blocks/builders/form_builder.rb +117 -0
  32. data/lib/action_blocks/builders/layout_builder.rb +15 -0
  33. data/lib/action_blocks/builders/model_builder.rb +566 -0
  34. data/lib/action_blocks/builders/summary_field_aggregation_functions.rb +41 -0
  35. data/lib/action_blocks/builders/table_builder.rb +259 -0
  36. data/lib/action_blocks/builders/workspace_builder.rb +282 -0
  37. data/lib/action_blocks/data_engine/authorization_adapter.rb +127 -0
  38. data/lib/action_blocks/data_engine/data_engine.rb +116 -0
  39. data/lib/action_blocks/data_engine/database_functions.rb +39 -0
  40. data/lib/action_blocks/data_engine/fields_engine.rb +103 -0
  41. data/lib/action_blocks/data_engine/filter_adapter.rb +105 -0
  42. data/lib/action_blocks/data_engine/filter_engine.rb +88 -0
  43. data/lib/action_blocks/data_engine/selections_via_where_engine.rb +134 -0
  44. data/lib/action_blocks/data_engine/summary_engine.rb +72 -0
  45. data/lib/action_blocks/engine.rb +5 -0
  46. data/lib/action_blocks/error.rb +62 -0
  47. data/lib/action_blocks/generator_helper.rb +134 -0
  48. data/lib/action_blocks/generators/action_blocks/model_block/USAGE +8 -0
  49. data/lib/action_blocks/generators/action_blocks/model_block/model_block_generator.rb +17 -0
  50. data/lib/action_blocks/generators/action_blocks/model_block/templates/model_block.rb +13 -0
  51. data/lib/action_blocks/generators/action_blocks/type/USAGE +8 -0
  52. data/lib/action_blocks/generators/action_blocks/type/templates/controller.rb +3 -0
  53. data/lib/action_blocks/generators/action_blocks/type/templates/dsl.rb +38 -0
  54. data/lib/action_blocks/generators/action_blocks/type/templates/type.css +3 -0
  55. data/lib/action_blocks/generators/action_blocks/type/templates/type.js +22 -0
  56. data/lib/action_blocks/generators/action_blocks/type/type_generator.rb +33 -0
  57. data/lib/action_blocks/store.rb +151 -0
  58. data/lib/action_blocks/version.rb +3 -0
  59. data/lib/generators/active_blocks/model_block/USAGE +8 -0
  60. data/lib/generators/active_blocks/model_block/model_block_generator.rb +17 -0
  61. data/lib/generators/active_blocks/model_block/templates/model_block.rb +13 -0
  62. data/lib/generators/active_blocks/type/USAGE +8 -0
  63. data/lib/generators/active_blocks/type/templates/controller.rb +3 -0
  64. data/lib/generators/active_blocks/type/templates/dsl.rb +38 -0
  65. data/lib/generators/active_blocks/type/templates/type.css +3 -0
  66. data/lib/generators/active_blocks/type/templates/type.js +22 -0
  67. data/lib/generators/active_blocks/type/type_generator.rb +33 -0
  68. data/lib/tasks/active_blocks_tasks.rake +4 -0
  69. metadata +128 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: a75a9346f84e224424ecd5353246ad7add3cf51236db4582edad2195e1e5ee5e
4
+ data.tar.gz: a63d8109813b23def1edbae53957734b135a835b8670ea2cf7698f7cf889e5c1
5
+ SHA512:
6
+ metadata.gz: dec0b245ea8c07e74fcc1bad08152b02b581cb84a5fa19b222041a5fb7a75f55da43c11d49a9bd66d9eec80f604929468cd4a99afbeab7050e5020db388d3dc8
7
+ data.tar.gz: 38360d45575e3c1672668301867391dcfd80674b37c61395e49abc12789c01ca63596c08313e9fff3044c4ebbc5fc6bc16aefb04f74075da78828308fa951df7
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2018 CTEH LLC
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,121 @@
1
+ # ActionBlocks
2
+ [![Travis](https://travis-ci.org/CTEH/action_blocks.svg?branch=master)](https://travis-ci.org/CTEH/action_blocks)
3
+
4
+ ActionBlocks is a Ruby On Rails engine for building administrative database-driven applications.
5
+
6
+ * Automates Backend and Frontend Development
7
+
8
+ * Supports Granular Authorization
9
+
10
+ * Leverages PostgreSQL for Performance
11
+
12
+ * Encourages Task Oriented UI
13
+
14
+
15
+ Automates Backend and Frontend Development
16
+ -------------------
17
+
18
+ A single low-code DSL is used to define both the backend and frontend.
19
+
20
+ ![ActionBlocks Diagram](https://raw.githubusercontent.com/CTEH/action_blocks/master/docs/single_dsl_diagram.png)
21
+
22
+ ```ruby
23
+ ActionBlocks.app do
24
+ title "My App"
25
+ workspace :main do
26
+ subspace :orders do
27
+ dashboard :all_orders do
28
+ table :list_all do
29
+ model :order
30
+ columns [:number, :employee, :customer, :status]
31
+ end
32
+ end
33
+
34
+ ...
35
+ ```
36
+
37
+ Supports Granular Authorization
38
+ ----------
39
+
40
+ Row Level Security (RLS) is defined for each role.
41
+
42
+ ```ruby
43
+ ActionBlock.authorize Post do
44
+ grant :reviewer do
45
+ _or(
46
+ _eq(:author_id, _user(:id)),
47
+ _eq(:status, 'Published')
48
+ ),
49
+ end
50
+ end
51
+ ```
52
+
53
+ Field Level Security (FLS) is defined for each role.
54
+
55
+ ```ruby
56
+ read do
57
+ read :employee, [:admin ]
58
+ read :customer, [:admin, :customer]
59
+ read :social_security [:admin, :customer]
60
+ read :order_date, [:admin, :customer]
61
+ read :shipped_date, [:admin, :customer]
62
+ read :ship_name, [:admin, :customer]
63
+ read :ship_address1, [:admin, :customer]
64
+ read :ship_address2, [:admin, :customer]
65
+ read :ship_city, [:admin, :customer]
66
+ read :ship_state, [:admin, :customer]
67
+ read :ship_postal_code, [:admin, :customer]
68
+ read :ship_country, [:admin, :customer]
69
+ read :shipping_fee, [:admin, :customer]
70
+ read :payment_type, [:admin, :customer]
71
+ read :paid_date, [:admin, :customer]
72
+ read :created_at, [:admin, :customer]
73
+ read :updated_at, [:admin, :customer]
74
+ read :region, [:admin, :customer]
75
+ read :referred_by, [:admin, :customer]
76
+ end
77
+
78
+ ```
79
+
80
+
81
+
82
+ Leverages PostgreSQL for Performance
83
+ ------------
84
+
85
+ ActionBlocks is similar to [Hasura](https://blog.hasura.io/architecture-of-a-high-performance-graphql-to-sql-server-58d9944b8a87) since it avoids N+1 queries and pushes JSON generation into PostgreSQL
86
+
87
+ * Uses an intelligent DSL managed data engine that avoids the N+1 problem associated with retrieving data in related tables and running authorization checks.
88
+
89
+ * Bypasses the performance tax of marshalling results to Objects and ultimately to JSON by pushing the transformation into PostgreSQL.
90
+
91
+ Encourages Task Oriented UI
92
+ ------------
93
+
94
+ Following the pholisophy of make the right thing the easy thing, ActionBlocks doesn't support CRUD. Instead it provides a rich DSL for Task Oriented UIs as explained https://cqrs.wordpress.com/documents/task-based-ui/
95
+
96
+
97
+
98
+ ## License
99
+ MIT License
100
+
101
+ Copyright (c) 2018 CTEH LLC
102
+
103
+ Permission is hereby granted, free of charge, to any person obtaining a copy
104
+ of this software and associated documentation files (the "Software"), to deal
105
+ in the Software without restriction, including without limitation the rights
106
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
107
+ copies of the Software, and to permit persons to whom the Software is
108
+ furnished to do so, subject to the following conditions:
109
+
110
+ The above copyright notice and this permission notice shall be included in all
111
+ copies or substantial portions of the Software.
112
+
113
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
114
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
115
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
116
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
117
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
118
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
119
+ SOFTWARE.
120
+
121
+
@@ -0,0 +1,33 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'ActionBlocks'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.md')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+ APP_RAKEFILE = File.expand_path("test/north_winds/Rakefile", __dir__)
18
+ load 'rails/tasks/engine.rake'
19
+
20
+ load 'rails/tasks/statistics.rake'
21
+
22
+ require 'bundler/gem_tasks'
23
+
24
+ require 'rake/testtask'
25
+
26
+ Rake::TestTask.new(:test) do |t|
27
+ t.libs << 'test'
28
+ t.pattern = 'test/**/*_test.rb'
29
+ t.verbose = false
30
+ t.warning = false
31
+ end
32
+
33
+ task default: :test
@@ -0,0 +1,2 @@
1
+ //= link_directory ../javascripts/action_blocks .js
2
+ //= link_directory ../stylesheets/action_blocks .css
@@ -0,0 +1,15 @@
1
+ // This is a manifest file that'll be compiled into application.js, which will include all the files
2
+ // listed below.
3
+ //
4
+ // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
+ // or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
6
+ //
7
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
+ // compiled file. JavaScript code in this file should be added after the last require_* statement.
9
+ //
10
+ // Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
11
+ // about supported directives.
12
+ //
13
+ //= require rails-ujs
14
+ //= require activestorage
15
+ //= require_tree .
@@ -0,0 +1,15 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the bottom of the
9
+ * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
10
+ * files in this directory. Styles in this file should be added after the last require_* statement.
11
+ * It is generally better to create a new file per style scope.
12
+ *
13
+ *= require_tree .
14
+ *= require_self
15
+ */
@@ -0,0 +1,22 @@
1
+ module ActionBlocks
2
+ class AttachmentsController < ActionController::Base
3
+ before_action :authenticate_user!
4
+
5
+ def download
6
+ model = ActionBlocks.find(params[:model_key])
7
+ if model == nil
8
+ raise RecordNotFound
9
+ end
10
+ id = params[:id]
11
+ field = params[:field]
12
+ record = model.active_model.find(id)
13
+ attachment = record.send(field)
14
+ begin
15
+ send_data attachment.download
16
+ rescue Module::DelegationError
17
+ raise ActiveRecord::RecordNotFound
18
+ end
19
+ end
20
+
21
+ end
22
+ end
@@ -0,0 +1,14 @@
1
+ module ActionBlocks
2
+ class BarchartBlocksController < ActionBlocks::BaseController
3
+ before_action :authenticate_user!
4
+
5
+ def analytics
6
+ block = ActionBlocks.find(params[:block_key])
7
+ user = nil
8
+ if block.calculate == :count
9
+ render plain: block.scope.call().group(block.group.column).count.to_json
10
+ end
11
+ end
12
+
13
+ end
14
+ end
@@ -0,0 +1,22 @@
1
+ module ActionBlocks
2
+
3
+ class BaseController < ApplicationController
4
+ # Disable need for authenticity token as we
5
+ # we are integrating with clients not rendered by rails
6
+
7
+ # JRH - https://labs.chiedo.com/blog/authenticating-your-reactjs-app-with-devise-no-extra-gems-needed/
8
+
9
+ before_action :validate_action_block
10
+ def validate_action_block
11
+ if Rails.env.development? || Rails.env.test?
12
+ if ActionBlocks.invalid?
13
+ Rails.logger.error "ActionBlock application invalid"
14
+ Rails.logger.error ActionBlocks.errors
15
+ raise "ActionBlock application invalid #{ActionBlocks.errors}"
16
+ end
17
+ end
18
+ end
19
+
20
+ end
21
+
22
+ end
@@ -0,0 +1,16 @@
1
+ module ActionBlocks
2
+ class BlocksController < BaseController
3
+ before_action :authenticate_user!
4
+ skip_before_action :validate_action_block
5
+
6
+ def index
7
+ user = nil
8
+ if ActionBlocks.invalid?
9
+ render json: {errors: ActionBlocks.errors}.to_json, content_type: 'application/json'
10
+ else
11
+ render json: ActionBlocks.hashify(user).to_json, content_type: 'application/json'
12
+ end
13
+ end
14
+
15
+ end
16
+ end
@@ -0,0 +1,6 @@
1
+ module ActionBlocks
2
+ class CommandBlocksController < BaseController
3
+ before_action :authenticate_user!
4
+
5
+ end
6
+ end
@@ -0,0 +1,13 @@
1
+ module ActionBlocks
2
+
3
+ class FormBlocksController < ActionBlocks::BaseController
4
+ before_action :authenticate_user!
5
+
6
+ def record
7
+ form = ActionBlocks.find(params[:block_key])
8
+ record_id = Integer(params[:record_id])
9
+ render json: form.record_to_json(user: current_user, record_id: record_id)
10
+ end
11
+
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ module ActionBlocks
2
+
3
+ class ModelBlocksController < ActionBlocks::BaseController
4
+ before_action :authenticate_user!
5
+
6
+ def name
7
+ model_block = ActionBlocks.find(params[:block_key])
8
+ record_id = Integer(params[:record_id])
9
+ render json: model_block.name_to_json(record_id: record_id, user: current_user)
10
+ end
11
+ end
12
+
13
+ end
@@ -0,0 +1,13 @@
1
+ module ActionBlocks
2
+ class TableBlocksController < ActionBlocks::BaseController
3
+ before_action :authenticate_user!
4
+
5
+ def records
6
+ params.permit([:block_key, :subspace_model_id, :dashboard_model_id])
7
+ user = current_user
8
+ table = ActionBlocks.find(params[:block_key])
9
+ render json: table.to_json(user: current_user, params: params)
10
+ end
11
+
12
+ end
13
+ end
@@ -0,0 +1,6 @@
1
+ module ActionBlocks
2
+ class WorkspaceBlocksController < ActionBlocks::BaseController
3
+ before_action :authenticate_user!
4
+
5
+ end
6
+ end
@@ -0,0 +1,4 @@
1
+ module ActionBlocks
2
+ module ApplicationHelper
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module ActionBlocks
2
+ class ApplicationJob < ActiveJob::Base
3
+ end
4
+ end
@@ -0,0 +1,6 @@
1
+ module ActionBlocks
2
+ class ApplicationMailer < ActionMailer::Base
3
+ default from: 'from@example.com'
4
+ layout 'mailer'
5
+ end
6
+ end
@@ -0,0 +1,5 @@
1
+ module ActionBlocks
2
+ class ApplicationRecord < ActiveRecord::Base
3
+ self.abstract_class = true
4
+ end
5
+ end
@@ -0,0 +1,16 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Active blocks</title>
5
+ <%= csrf_meta_tags %>
6
+ <%= csp_meta_tag %>
7
+
8
+ <%= stylesheet_link_tag "action_blocks/application", media: "all" %>
9
+ <%= javascript_include_tag "action_blocks/application" %>
10
+ </head>
11
+ <body>
12
+
13
+ <%= yield %>
14
+
15
+ </body>
16
+ </html>
@@ -0,0 +1,9 @@
1
+ def database_exists?
2
+ ActiveRecord::Base.connection
3
+ rescue ActiveRecord::NoDatabaseError
4
+ false
5
+ else
6
+ true
7
+ end
8
+
9
+ ActionBlocks.initial_load if database_exists?
@@ -0,0 +1,10 @@
1
+ ActionBlocks::Engine.routes.draw do
2
+ get "action_blocks/blocks", to: "blocks#blocks"
3
+ get "table_blocks/:block_key(/:subspace_model_id)(/:dashboard_model_id)/records", to: "table_blocks#records"
4
+ get "form_blocks/:block_key/:record_id/record", to: "form_blocks#record"
5
+ get "blocks", to: "blocks#index"
6
+ get "barchart_blocks/:block_key/analytics", to: "barchart_blocks#analytics"
7
+ get "model_blocks/:block_key/:record_id/name", to: "model_blocks#name"
8
+ get 'attachments/:model_key/:id/:field' => "attachments#download"
9
+
10
+ end
@@ -0,0 +1,120 @@
1
+ # require 'active_admin/reloader'
2
+
3
+ module ActionBlocks
4
+ class Loader
5
+
6
+ attr_reader :application, :load_paths
7
+ def initialize(path)
8
+ @load_paths = [File.expand_path(path, Rails.root)]
9
+ end
10
+
11
+ # Whether all configuration files have been loaded
12
+ def loaded?
13
+ @@loaded ||= false
14
+ end
15
+
16
+ # Removes all defined controllers from memory. Useful in
17
+ # development, where they are reloaded on each request.
18
+ def unload!
19
+ ActionBlocks.unload!
20
+ @@loaded = false
21
+ end
22
+
23
+ # Loads all ruby files that are within the load_paths setting.
24
+ # To reload everything simply call `ActionBlocks.unload!`
25
+ def load!
26
+ Rails.logger.debug "ActionBlocks::Loader load!()"
27
+ Rails.logger.debug " loaded?:#{loaded?().inspect}"
28
+ unless loaded?
29
+ # ActiveSupport::Notifications.publish BeforeLoadEvent, self # before_load hook
30
+ files.each{ |file| load file } # load files
31
+ # ActiveSupport::Notifications.publish AfterLoadEvent, self # after_load hook
32
+ @@loaded = true
33
+ end
34
+ end
35
+
36
+ def load(file)
37
+ Rails.logger.debug "ActionBlocks::Loader load(#{file})"
38
+ DatabaseHitDuringLoad.capture{ super }
39
+ end
40
+
41
+ # Returns ALL the files to be loaded
42
+ def files
43
+ load_paths.flatten.compact.uniq.flat_map{ |path| Dir["#{path}/**/*.rb"] }
44
+ end
45
+
46
+ # Since app/blocks is alphabetically before app/models, we have to remove it
47
+ # from the host app's +autoload_paths+ to prevent missing constant errors.
48
+ #
49
+ # As well, we have to remove it from +eager_load_paths+ to prevent the
50
+ # files from being loaded twice in production.
51
+ def remove_active_admin_load_paths_from_rails_autoload_and_eager_load
52
+ ActiveSupport::Dependencies.autoload_paths -= load_paths
53
+ Rails.application.config.eager_load_paths -= load_paths
54
+ end
55
+
56
+ # Hook into the Rails code reloading mechanism so that things are reloaded
57
+ # properly in development mode.
58
+ #
59
+ # If any of the app files (e.g. models) has changed, we need to reload all
60
+ # the admin files. If the admin files themselves has changed, we need to
61
+ # regenerate the routes as well.
62
+ def attach_reloader
63
+ # ActiveSupport::Reloader.to_prepare(*args, &block)
64
+ Rails.application.config.after_initialize do |app|
65
+ if app.config.reload_classes_only_on_change
66
+ # Rails is about to unload all the app files (e.g. models), so we
67
+ # should first unload the classes generated by Active Admin, otherwise
68
+ # they will contain references to the stale (unloaded) classes.
69
+ ActiveSupport::Reloader.to_prepare(prepend: true) do
70
+ ActionBlocks.unload!
71
+ end
72
+ else
73
+ # If the user has configured the app to always reload app files after
74
+ # each request, so we should unload the generated classes too.
75
+ ActiveSupport::Reloader.to_complete() do
76
+ puts "ActiveSupport::Reloader.to_complete()\n"
77
+ # ActionBlocks.application.unload!
78
+ # @@loaded = false
79
+ end
80
+ end
81
+
82
+ # block_drs = {}
83
+ #
84
+ # load_paths.each do |path|
85
+ # block_drs[path] = [:rb]
86
+ # end
87
+
88
+ # routes_reloader = app.config.file_watcher.new([], block_drs) do
89
+ # app.reload_routes!
90
+ # end
91
+ #
92
+ # app.reloaders << routes_reloader
93
+
94
+ ActiveSupport::Reloader.to_prepare do
95
+ # Rails.logger.debug("--> 1. ActionBlocks::Loader.new('app/blocks')")
96
+ loader = ActionBlocks::Loader.new('app/blocks')
97
+ loader.unload!
98
+ loader.load!
99
+ ActionBlocks.after_load
100
+
101
+ # loader.attach_reloader
102
+ # Rails might have reloaded the routes for other reasons (e.g.
103
+ # routes.rb has changed), in which case Active Admin would have been
104
+ # loaded via the `ActiveAdmin.routes` call in `routes.rb`.
105
+ #
106
+ # Otherwise, we should check if any of the admin files are changed
107
+ # and force the routes to reload if necessary. This would again causes
108
+ # Active Admin to load via `ActiveAdmin.routes`.
109
+ #
110
+ # Finally, if Active Admin is still not loaded at this point, then we
111
+ # would need to load it manually.
112
+ # unless ActionBlocks.application.loaded?
113
+ # routes_reloader.execute_if_updated
114
+ # self.load!
115
+ # end
116
+ end
117
+ end
118
+ end #attach_reloader
119
+ end
120
+ end