rolemodel-rails 2.3.1 → 2.4.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.
- checksums.yaml +4 -4
- data/README.md +92 -0
- data/lib/generators/rolemodel/linters/eslint/eslint_generator.rb +1 -2
- data/lib/generators/rolemodel/optics/base/base_generator.rb +1 -2
- data/lib/generators/rolemodel/react/react_generator.rb +1 -2
- data/lib/generators/rolemodel/sentry/sentry_generator.rb +1 -2
- data/lib/generators/rolemodel/tailored_select/tailored_select_generator.rb +1 -2
- data/lib/generators/rolemodel/testing/jasmine_playwright/jasmine_playwright_generator.rb +4 -8
- data/lib/generators/rolemodel/testing/rspec/rspec_generator.rb +2 -3
- data/lib/generators/rolemodel/testing/vitest/vitest_generator.rb +6 -7
- data/lib/generators/rolemodel/turbo/confirm/confirm_generator.rb +1 -2
- data/lib/generators/rolemodel/turbo/form/form_generator.rb +1 -2
- data/lib/generators/rolemodel/ui_components/navbar/navbar_generator.rb +1 -2
- data/lib/generators/rolemodel/webpack/webpack_generator.rb +2 -8
- data/lib/rolemodel/engine.rb +7 -0
- data/lib/rolemodel/generator_base.rb +7 -1
- data/lib/rolemodel/resource_for/controller_extension.rb +15 -0
- data/lib/rolemodel/version.rb +1 -1
- data/lib/rolemodel/yarn.rb +2 -3
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 41af565ee256cafc1b08a53dcdce9bf029e1503d8a368d2e946bb4bebec284a2
|
|
4
|
+
data.tar.gz: f7247392ea0c87346ba0915d14506852f34ced3380331905e7e9209f4b2436d7
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f5fe95adeb421eb88bf8c04e9630b6c688403237fd09b68b4185391254430d12161cd3de74cceabda0b11680a56ee2848fba273b2070a3bc36b7a5ce3701b29d
|
|
7
|
+
data.tar.gz: 89343467c51120526e7ef218d3037fdeb920b75ab846ba5c09a45464897e6484db0532d70d66bf9a3d3477d3d2c13bf34197fe432fd980ff47ad1d6ca50ef058
|
data/README.md
CHANGED
|
@@ -219,6 +219,98 @@ DRY_RUN=true rake users:dev[_,bob@example.com]
|
|
|
219
219
|
#=> -> 0.0000s
|
|
220
220
|
```
|
|
221
221
|
|
|
222
|
+
### `Rolemodel::ResourceFor::ControllerExtension`
|
|
223
|
+
|
|
224
|
+
Provides the private `resource_for` utility method to all controller classes throughout your app. Use it in conjunction with Routing concerns.
|
|
225
|
+
|
|
226
|
+
#### The Problem It Solves
|
|
227
|
+
|
|
228
|
+
Apps accumulate resources that hang off many different parents. Good examples include `comments`, `reports`, `duplications`.
|
|
229
|
+
|
|
230
|
+
The naive approach involves many namespaced controllers that all do the same thing but with a different parent resource, or adding several non-restful actions to each parent controller.
|
|
231
|
+
|
|
232
|
+
The following example illustrates a better pattern.
|
|
233
|
+
|
|
234
|
+
##### Routing
|
|
235
|
+
|
|
236
|
+
Declare the child resource inside a route concern and pass the parent's class name as a route default using `parent_resource`:
|
|
237
|
+
|
|
238
|
+
```ruby
|
|
239
|
+
concern :commentable do
|
|
240
|
+
resources :comments, commentable_type: parent_resource.name.classify
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
concern :reportable do
|
|
244
|
+
resources :generated_reports, only: %i[show create], reportable_type: parent_resource.name.classify
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
shallow do
|
|
248
|
+
resources :accounts do
|
|
249
|
+
resources :estimates, concerns: %i[commentable reportable] do
|
|
250
|
+
resources :widgets, concerns: %i[commentable reportable]
|
|
251
|
+
end
|
|
252
|
+
end
|
|
253
|
+
end
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
##### Controller
|
|
257
|
+
|
|
258
|
+
One controller serves every parent:
|
|
259
|
+
|
|
260
|
+
```ruby
|
|
261
|
+
class CommentsController < ApplicationController
|
|
262
|
+
before_action :set_commentable, only: %i[index new create]
|
|
263
|
+
before_action :set_comment, except: %i[index new create]
|
|
264
|
+
|
|
265
|
+
def create
|
|
266
|
+
# ...
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
private
|
|
270
|
+
|
|
271
|
+
def set_commentable
|
|
272
|
+
@commentable = resource_for(:commentable_type) # pass in the symbol specified in your routing concern.
|
|
273
|
+
end
|
|
274
|
+
end
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
Under `shallow: true`, only the collection actions (`index`, `new`, `create`) carry the parent id — hence the `only:`/`except:` split above. Member actions find the child directly by `params[:id]` and reach the parent through its own association.
|
|
278
|
+
|
|
279
|
+
`resource_for` returns the record itself, so it composes with authorization and presentation:
|
|
280
|
+
|
|
281
|
+
```ruby
|
|
282
|
+
def set_resource
|
|
283
|
+
@resource = authorize resource_for(:resource_type)
|
|
284
|
+
end
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
#### Guarding User-Supplied Types
|
|
288
|
+
|
|
289
|
+
Route defaults are merged into `params` last, so a route-supplied type cannot be overridden by a query string or request body. If a type ever arrives from user input instead, allowlist it before calling `resource_for` — `safe_constantize` will happily resolve any constant in the app:
|
|
290
|
+
|
|
291
|
+
```ruby
|
|
292
|
+
REPORT_CONTEXTS = %w[Accessory Estimate PartProxy Tank].freeze
|
|
293
|
+
|
|
294
|
+
before_action :verify_context_type, :set_context, only: %i[create]
|
|
295
|
+
|
|
296
|
+
private
|
|
297
|
+
|
|
298
|
+
def verify_context_type
|
|
299
|
+
return if REPORT_CONTEXTS.include?(params[:context_type])
|
|
300
|
+
|
|
301
|
+
redirect_back_or_to root_url, alert: 'Invalid Request'
|
|
302
|
+
end
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
Doing this even for route-supplied types is cheap insurance: it documents which parents the controller actually supports and fails loudly when a new route wires up a parent the controller cannot handle.
|
|
306
|
+
|
|
307
|
+
#### Notes
|
|
308
|
+
|
|
309
|
+
* Raises `ActiveRecord::RecordNotFound` when the id does not resolve, which Rails renders as a 404 — the same behavior as any other `find`.
|
|
310
|
+
* `safe_constantize` returns `nil` for an unknown constant, producing a `NoMethodError`; allowlisting avoids that.
|
|
311
|
+
* The class name is demodulized when deriving the id param, so `Reporting::Tank` looks for `params[:tank_id]`.
|
|
312
|
+
* Included via `ActiveSupport.on_load(:action_controller_base)`, so `ActionController::API` controllers do not get it.
|
|
313
|
+
|
|
222
314
|
## Development
|
|
223
315
|
|
|
224
316
|
Install the versions of Node and Ruby specified in `.node-version` and `.ruby-version` on your machine. https://asdf-vm.com/ is a great tool for managing language versions. Then run `corepack enable` to activate the Yarn 4+ version pinned by each project's `packageManager` field.
|
|
@@ -18,8 +18,10 @@ module Rolemodel
|
|
|
18
18
|
raise Thor::InvocationError, 'a --github_package_token option or GITHUB_PACKAGES_TOKEN environment variable is required' if options[:github_package_token].blank?
|
|
19
19
|
end
|
|
20
20
|
|
|
21
|
-
def
|
|
22
|
-
|
|
21
|
+
def add_dev_dependencies
|
|
22
|
+
say 'Adding new dev dependency to package.json', :green
|
|
23
|
+
|
|
24
|
+
yarn_command "add --dev #{DEV_DEPENDENCIES.join(' ')}"
|
|
23
25
|
end
|
|
24
26
|
|
|
25
27
|
def add_browser_test_script
|
|
@@ -34,12 +36,6 @@ module Rolemodel
|
|
|
34
36
|
create_file '.node-version', NODE_VERSION, force: true
|
|
35
37
|
end
|
|
36
38
|
|
|
37
|
-
def add_dev_dependencies
|
|
38
|
-
say 'Adding new dev dependency to package.json', :green
|
|
39
|
-
|
|
40
|
-
run "yarn add --dev #{DEV_DEPENDENCIES.join(' ')}"
|
|
41
|
-
end
|
|
42
|
-
|
|
43
39
|
def add_spec_config_files
|
|
44
40
|
say 'Adding Jasmine Playwright configuration files', :green
|
|
45
41
|
|
|
@@ -27,9 +27,8 @@ module Rolemodel
|
|
|
27
27
|
def install_playwright
|
|
28
28
|
say 'Installing Playwright for system tests', :green
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
run 'yarn run playwright install'
|
|
30
|
+
yarn_command 'add --dev playwright'
|
|
31
|
+
yarn_command 'run playwright install'
|
|
33
32
|
end
|
|
34
33
|
|
|
35
34
|
def add_spec_files
|
|
@@ -14,17 +14,16 @@ module Rolemodel
|
|
|
14
14
|
@vitest/ui
|
|
15
15
|
].freeze
|
|
16
16
|
|
|
17
|
-
def
|
|
18
|
-
say '
|
|
19
|
-
ensure_yarn
|
|
17
|
+
def add_dev_dependencies
|
|
18
|
+
say 'Adding new dev dependency to package.json', :green
|
|
20
19
|
|
|
21
|
-
|
|
20
|
+
yarn_command "add --dev #{DEV_DEPENDENCIES.join(' ')}"
|
|
22
21
|
end
|
|
23
22
|
|
|
24
|
-
def
|
|
25
|
-
say '
|
|
23
|
+
def update_test_script
|
|
24
|
+
say 'Update yarn test command', :green
|
|
26
25
|
|
|
27
|
-
|
|
26
|
+
add_package_json_script 'test', TEST_COMMAND
|
|
28
27
|
end
|
|
29
28
|
|
|
30
29
|
def add_spec_config_files
|
|
@@ -41,12 +41,6 @@ module Rolemodel
|
|
|
41
41
|
create_file '.node-version', NODE_VERSION, force: true
|
|
42
42
|
end
|
|
43
43
|
|
|
44
|
-
def enable_corepack_and_yarn
|
|
45
|
-
say 'Enabling Corepack and pinning the project to Yarn 4+', :green
|
|
46
|
-
|
|
47
|
-
ensure_yarn
|
|
48
|
-
end
|
|
49
|
-
|
|
50
44
|
def force_node_to_use_es_modules
|
|
51
45
|
say 'Configuring project to use ES Modules instead of CommonJS', :green
|
|
52
46
|
|
|
@@ -56,14 +50,14 @@ module Rolemodel
|
|
|
56
50
|
def remove_obsolete_javascript_dependencies
|
|
57
51
|
say 'Removing webpack & webpack-cli from package.json dependencies', :green
|
|
58
52
|
|
|
59
|
-
|
|
53
|
+
yarn_command 'remove webpack webpack-cli'
|
|
60
54
|
end
|
|
61
55
|
|
|
62
56
|
def add_npm_packages
|
|
63
57
|
say 'Adding new dev dependencies to package.json', :green
|
|
64
58
|
|
|
65
59
|
dependencies = DEV_DEPS + POSTCSS_PKGS + WEBPACK_CSS_PKGS
|
|
66
|
-
|
|
60
|
+
yarn_command "add --dev #{dependencies.join(' ')}"
|
|
67
61
|
end
|
|
68
62
|
|
|
69
63
|
def add_webpack_config
|
data/lib/rolemodel/engine.rb
CHANGED
|
@@ -3,9 +3,16 @@
|
|
|
3
3
|
module Rolemodel
|
|
4
4
|
class Engine < ::Rails::Engine
|
|
5
5
|
require_relative 'generator_base'
|
|
6
|
+
require_relative 'resource_for/controller_extension'
|
|
6
7
|
|
|
7
8
|
generators do
|
|
8
9
|
require 'generators/rolemodel/all_generator'
|
|
9
10
|
end
|
|
11
|
+
|
|
12
|
+
initializer 'rolemodel.action_controller' do
|
|
13
|
+
ActiveSupport.on_load(:action_controller_base) do
|
|
14
|
+
include Rolemodel::ResourceFor::ControllerExtension
|
|
15
|
+
end
|
|
16
|
+
end
|
|
10
17
|
end
|
|
11
18
|
end
|
|
@@ -9,19 +9,25 @@ module Rolemodel
|
|
|
9
9
|
class GeneratorBase < ::Rails::Generators::Base
|
|
10
10
|
include ::Rails::Generators::BundleHelper, ReplaceContentHelper
|
|
11
11
|
|
|
12
|
-
|
|
13
12
|
private
|
|
14
13
|
# based on https://github.com/rails/rails/blob/main/railties/lib/rails/generators/app_base.rb#L713
|
|
15
14
|
def run_bundle
|
|
16
15
|
bundle_command("install --quiet", "BUNDLE_IGNORE_MESSAGES" => "1")
|
|
17
16
|
end
|
|
18
17
|
|
|
18
|
+
def yarn_command(command)
|
|
19
|
+
ensure_yarn
|
|
20
|
+
|
|
21
|
+
run "yarn #{command}"
|
|
22
|
+
end
|
|
23
|
+
|
|
19
24
|
# Enable Corepack and pin the project to Yarn 4+ before running any `yarn`
|
|
20
25
|
# command. Empty args/opts are required: without them, Thor forwards this
|
|
21
26
|
# generator's own CLI args (e.g. the test harness's --skip-bundle
|
|
22
27
|
# --skip-bootsnap) into Rolemodel::Yarn#setup, which takes none and raises
|
|
23
28
|
# Thor::InvocationError.
|
|
24
29
|
def ensure_yarn
|
|
30
|
+
return if Rails.root.join(destination_root, '.yarnrc.yml').exist?
|
|
25
31
|
invoke 'rolemodel:yarn:setup', [], {}
|
|
26
32
|
end
|
|
27
33
|
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Rolemodel
|
|
4
|
+
module ResourceFor
|
|
5
|
+
module ControllerExtension
|
|
6
|
+
extend ActiveSupport::Concern
|
|
7
|
+
|
|
8
|
+
private
|
|
9
|
+
|
|
10
|
+
def resource_for(type_symbol)
|
|
11
|
+
params[type_symbol].safe_constantize.find(params[params[type_symbol].foreign_key])
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
data/lib/rolemodel/version.rb
CHANGED
data/lib/rolemodel/yarn.rb
CHANGED
|
@@ -5,11 +5,10 @@ module Rolemodel
|
|
|
5
5
|
class Yarn < ::Thor
|
|
6
6
|
include ::Thor::Actions
|
|
7
7
|
|
|
8
|
-
# Enable Corepack and pin the project to Yarn 4+ (instead of the classic
|
|
9
|
-
# Yarn 1.22). Idempotent, so any generator can call it before running a
|
|
10
|
-
# `yarn` command to guarantee the modern toolchain is in place.
|
|
8
|
+
# Enable Corepack and pin the project to Yarn 4+ (instead of the classic Yarn 1.22).
|
|
11
9
|
desc 'setup', 'Set the current stable version of Yarn, enable corepack, and initialize a package.json file'
|
|
12
10
|
def setup
|
|
11
|
+
say 'Setting up Yarn 4+ and Corepack', :green
|
|
13
12
|
# Configure the node-modules linker so webpack, Playwright, and the Rails
|
|
14
13
|
# asset pipeline keep working (Yarn 4 defaults to Plug'n'Play otherwise).
|
|
15
14
|
# skip if exists? to avoid overwriting any other existing config
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rolemodel-rails
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.
|
|
4
|
+
version: 2.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- RoleModel Software Inc
|
|
@@ -436,6 +436,7 @@ files:
|
|
|
436
436
|
- lib/rolemodel/optics/phosphor_icon_builder.rb
|
|
437
437
|
- lib/rolemodel/optics/tabler_icon_builder.rb
|
|
438
438
|
- lib/rolemodel/replace_content_helper.rb
|
|
439
|
+
- lib/rolemodel/resource_for/controller_extension.rb
|
|
439
440
|
- lib/rolemodel/utility.rb
|
|
440
441
|
- lib/rolemodel/utility/task_tools.rb
|
|
441
442
|
- lib/rolemodel/version.rb
|