thecore_generators 3.1.0 → 3.2.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 +80 -7
- data/lib/generators/thecore/model/model_generator.rb +41 -15
- data/lib/thecore_generators/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 48198bd6f914066ca468eae2e95cb9dba85003d49532b1db28f8620db3c40b21
|
|
4
|
+
data.tar.gz: 7a3e542b82e0ff43691e3a988dad6e42f59fc51da0e460220e5481881eb55ba3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 82748585f40f3f1e3975a3c1186d4bb98a3d8c4963ebcb495d9ba4c3c86701b2a48e981c28a6bfe220bd20b90fbcdacffa7e332b36edcbba2d4c3ab80e097e0d
|
|
7
|
+
data.tar.gz: ca82db7bdc678f66789b0ed9af24bf28f4f2253e2c025c3972118e602a86e662fc845863b098ba220d3163739c30b73f2588b30eb0aa8384300bc86a25adf013
|
data/README.md
CHANGED
|
@@ -26,13 +26,23 @@ transparently apply thecore's scaffolding conventions — no new command vocabul
|
|
|
26
26
|
`app/models`/`db/migrate`/`test` instead of the host app's. Pass `--atom=NAME` to
|
|
27
27
|
override detection explicitly (works independent of `cwd`, e.g. from CI or the host-app
|
|
28
28
|
root).
|
|
29
|
-
- **
|
|
30
|
-
are generated
|
|
31
|
-
`addModel.js` templates do today.
|
|
32
|
-
- **No `Endpoints::ModelName` by default** (per
|
|
29
|
+
- **No concern files by default.** `Api::ModelName`/`RailsAdmin::ModelName` concern files
|
|
30
|
+
are **not** generated (per
|
|
33
31
|
[ADR 0001](https://github.com/gabrieletassoni/thecore/blob/release/3/docs/adr/0001-application-record-defaults-over-generated-concerns.md)) —
|
|
34
|
-
|
|
35
|
-
|
|
32
|
+
the no-customization case relies entirely on the default `json_attrs`/`navigation_label`/
|
|
33
|
+
`navigation_icon` behavior that `model_driven_api` and `thecore_ui_rails_admin` `include`
|
|
34
|
+
into every `ApplicationRecord` subclass automatically
|
|
35
|
+
(`ThecoreBackendCommons::DefaultModuleRegistry`). Pass `--with-api-concern` and/or
|
|
36
|
+
`--with-admin-concern` to scaffold a starter concern file — identical in shape to what
|
|
37
|
+
this generator produced before this default changed — for the case where customization
|
|
38
|
+
is already known to be needed at generation time:
|
|
39
|
+
```bash
|
|
40
|
+
rails generate model Foo name:string --with-api-concern --with-admin-concern
|
|
41
|
+
```
|
|
42
|
+
See "Adding a concern by hand" below for the (more common) case of realizing
|
|
43
|
+
customization is needed *after* the model already exists.
|
|
44
|
+
- **No `Endpoints::ModelName` by default** (per ADR 0001) — add one by hand, following the
|
|
45
|
+
`after_initialize` + `class_eval` pattern, only when a real custom action is needed.
|
|
36
46
|
- **Test file generation is never suppressed** — a real Minitest file is generated, same
|
|
37
47
|
as Rails' own `active_record:model` default.
|
|
38
48
|
- **`rails generate active_record:model`/`active_record:migration` still work directly**
|
|
@@ -40,9 +50,60 @@ transparently apply thecore's scaffolding conventions — no new command vocabul
|
|
|
40
50
|
|
|
41
51
|
Both `Thecore::Generators::ModelGenerator` and `MigrationGenerator` wrap (not reimplement)
|
|
42
52
|
`ActiveRecord::Generators::ModelGenerator`/`MigrationGenerator` — all attribute parsing and
|
|
43
|
-
template content is inherited as-is; only file placement and the two
|
|
53
|
+
template content is inherited as-is; only file placement and the two opt-in concerns are
|
|
44
54
|
added on top.
|
|
45
55
|
|
|
56
|
+
### Adding a concern by hand
|
|
57
|
+
|
|
58
|
+
The common case is not knowing at `rails generate model` time that a model will need
|
|
59
|
+
custom API serialization or RailsAdmin configuration — that need usually surfaces later.
|
|
60
|
+
Since neither concern is generated by default, add the missing one directly instead of
|
|
61
|
+
regenerating the model:
|
|
62
|
+
|
|
63
|
+
**`Api::ModelName`** (custom `json_attrs`) — create `app/models/concerns/api/model_name.rb`:
|
|
64
|
+
```ruby
|
|
65
|
+
module Api::ModelName
|
|
66
|
+
extend ActiveSupport::Concern
|
|
67
|
+
|
|
68
|
+
included do
|
|
69
|
+
cattr_accessor :json_attrs
|
|
70
|
+
self.json_attrs = ::ModelDrivenApi.smart_merge(json_attrs || {}), { only: [:id, :name] }
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
```
|
|
74
|
+
then `include Api::ModelName` in the model. Because the default module (`model_driven_api`'s
|
|
75
|
+
`ModelDrivenApiDefaultJsonAttrs`) is already `include`d by the time the model class body
|
|
76
|
+
runs, `::ModelDrivenApi.smart_merge(json_attrs || {}, ...)` composes on top of it rather
|
|
77
|
+
than starting from nothing — the same pattern the opt-in `--with-api-concern` template
|
|
78
|
+
below uses.
|
|
79
|
+
|
|
80
|
+
**`RailsAdmin::ModelName`** (custom admin config) — create
|
|
81
|
+
`app/models/concerns/rails_admin/model_name.rb`:
|
|
82
|
+
```ruby
|
|
83
|
+
module RailsAdmin::ModelName
|
|
84
|
+
extend ActiveSupport::Concern
|
|
85
|
+
|
|
86
|
+
included do
|
|
87
|
+
rails_admin do
|
|
88
|
+
navigation_label I18n.t('admin.registries.label')
|
|
89
|
+
navigation_icon 'fa fa-file' # see https://fontawesome.com/v5/search
|
|
90
|
+
configure :some_field do
|
|
91
|
+
hide
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
```
|
|
97
|
+
then `include RailsAdmin::ModelName` in the model. RailsAdmin evaluates same-origin
|
|
98
|
+
`rails_admin do ... end` blocks in registration order and later calls win on settings they
|
|
99
|
+
touch (`navigation_label`/`navigation_icon` are last-write-wins setters) — so this explicit
|
|
100
|
+
block, `include`d after the default from the class body, overrides the default's
|
|
101
|
+
`navigation_label`/`navigation_icon` while the default itself keeps applying to every other
|
|
102
|
+
model that has no concern of its own.
|
|
103
|
+
|
|
104
|
+
Either concern can be added independently — a model doesn't need both just because it
|
|
105
|
+
needs one.
|
|
106
|
+
|
|
46
107
|
## Installation
|
|
47
108
|
|
|
48
109
|
Add to your host app's or ATOM's `Gemfile`:
|
|
@@ -55,12 +116,24 @@ gem "thecore_generators", "~> 3.0"
|
|
|
55
116
|
|
|
56
117
|
Tests use a `Rails::Generators::TestCase`-based harness against the `test/dummy` Rails
|
|
57
118
|
app included in this repo (needed to exercise generators the way a real host app would).
|
|
119
|
+
`test/dummy` also boots real `model_driven_api`/`thecore_ui_rails_admin` (and their own
|
|
120
|
+
transitive `thecore_backend_commons`/`thecore_auth_commons` dependencies) as temporary
|
|
121
|
+
git-based dependencies — see the Gemfile's comment — purely so
|
|
122
|
+
`test/generators/thecore/model_generator_default_concern_behavior_test.rb` can prove the
|
|
123
|
+
no-concern default actually works at runtime, not just that no file was written.
|
|
58
124
|
|
|
59
125
|
```bash
|
|
60
126
|
bundle install
|
|
61
127
|
bundle exec rake test
|
|
62
128
|
```
|
|
63
129
|
|
|
130
|
+
If your shell has `DATABASE_URL` set to a PostgreSQL URL (e.g. inside the Thecore
|
|
131
|
+
devcontainer), unset it first — it overrides `test/dummy`'s own SQLite3 test config:
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
env -u DATABASE_URL bundle exec rake test
|
|
135
|
+
```
|
|
136
|
+
|
|
64
137
|
`bundle exec rake` alone runs the same suite (`test` is the default Rake task).
|
|
65
138
|
|
|
66
139
|
To run a single test file:
|
|
@@ -14,11 +14,19 @@ module Thecore
|
|
|
14
14
|
# generation are inherited as-is. On top of that:
|
|
15
15
|
# - Thecore::Generators::AtomAware redirects placement into an ATOM's
|
|
16
16
|
# app/models + db/migrate when one is detected (see its own docs).
|
|
17
|
-
# - `Api::ModelName`/`RailsAdmin::ModelName` concern files are
|
|
18
|
-
# generated
|
|
19
|
-
#
|
|
20
|
-
#
|
|
21
|
-
#
|
|
17
|
+
# - `Api::ModelName`/`RailsAdmin::ModelName` concern files are NOT
|
|
18
|
+
# generated by default (thecore_generators#4 / ADR 0001 in the
|
|
19
|
+
# thecore repo): the no-customization case now relies entirely on
|
|
20
|
+
# the default `json_attrs`/`navigation_label`/`navigation_icon`
|
|
21
|
+
# modules that `model_driven_api` and `thecore_ui_rails_admin`
|
|
22
|
+
# `include` into every `ApplicationRecord` subclass automatically
|
|
23
|
+
# (`ThecoreBackendCommons::DefaultModuleRegistry`). Pass
|
|
24
|
+
# `--with-api-concern`/`--with-admin-concern` to scaffold a starter
|
|
25
|
+
# concern file — identical in shape to what this generator produced
|
|
26
|
+
# before this ticket — for the case where customization is already
|
|
27
|
+
# known to be needed at generation time. To add one later instead
|
|
28
|
+
# (the common case), see the "Adding a concern by hand" section of
|
|
29
|
+
# this gem's README.
|
|
22
30
|
# - `Endpoints::ModelName` is deliberately NOT generated (ADR 0001: it's
|
|
23
31
|
# never `include`d by default; add it by hand, following the
|
|
24
32
|
# after_initialize + class_eval pattern, only when a real custom
|
|
@@ -29,6 +37,15 @@ module Thecore
|
|
|
29
37
|
class ModelGenerator < ActiveRecord::Generators::ModelGenerator
|
|
30
38
|
include Thecore::Generators::AtomAware
|
|
31
39
|
|
|
40
|
+
class_option :with_api_concern, type: :boolean, default: false,
|
|
41
|
+
desc: "Scaffold a starter app/models/concerns/api/<model>.rb, included into the model " \
|
|
42
|
+
"(pre-thecore_generators#4 default behavior). Opt in only when customization is " \
|
|
43
|
+
"already known to be needed at generation time."
|
|
44
|
+
class_option :with_admin_concern, type: :boolean, default: false,
|
|
45
|
+
desc: "Scaffold a starter app/models/concerns/rails_admin/<model>.rb, included into the " \
|
|
46
|
+
"model (pre-thecore_generators#4 default behavior). Opt in only when customization is " \
|
|
47
|
+
"already known to be needed at generation time."
|
|
48
|
+
|
|
32
49
|
# `source_root` (singular) must be set explicitly: Rails::Generators::Base's
|
|
33
50
|
# auto-computed `default_source_root` derives its path from *this*
|
|
34
51
|
# class's own base_name/generator_name ("thecore"/"model"), which
|
|
@@ -42,30 +59,39 @@ module Thecore
|
|
|
42
59
|
|
|
43
60
|
def create_model_file
|
|
44
61
|
super
|
|
45
|
-
|
|
62
|
+
add_opted_in_concerns
|
|
46
63
|
end
|
|
47
64
|
|
|
48
65
|
private
|
|
49
66
|
|
|
50
67
|
# Faithful Ruby port of addModel.js's api_concern.rb/rails_admin_concern.rb
|
|
51
68
|
# templates and its `include Api::X` / `include RailsAdmin::X` model-file
|
|
52
|
-
# rewrite — down to the exact generated content —
|
|
53
|
-
#
|
|
54
|
-
#
|
|
55
|
-
def
|
|
56
|
-
|
|
57
|
-
|
|
69
|
+
# rewrite — down to the exact generated content — kept available behind
|
|
70
|
+
# `--with-api-concern`/`--with-admin-concern` for the explicit
|
|
71
|
+
# customization-at-generation-time case (thecore_generators#4).
|
|
72
|
+
def add_opted_in_concerns
|
|
73
|
+
include_lines = +""
|
|
74
|
+
|
|
75
|
+
if options[:with_api_concern]
|
|
76
|
+
template "api_concern.rb", File.join("app/models/concerns/api", class_path, "#{file_name}.rb")
|
|
77
|
+
include_lines << " include Api::#{class_name}\n"
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
if options[:with_admin_concern]
|
|
81
|
+
template "rails_admin_concern.rb", File.join("app/models/concerns/rails_admin", class_path, "#{file_name}.rb")
|
|
82
|
+
include_lines << " include RailsAdmin::#{class_name}\n"
|
|
83
|
+
end
|
|
58
84
|
|
|
59
|
-
|
|
85
|
+
include_opted_in_concerns_in_model(include_lines) unless include_lines.empty?
|
|
60
86
|
end
|
|
61
87
|
|
|
62
|
-
def
|
|
88
|
+
def include_opted_in_concerns_in_model(include_lines)
|
|
63
89
|
model_file = File.join("app/models", class_path, "#{file_name}.rb")
|
|
64
90
|
simple_class_name = class_name.split("::").last
|
|
65
91
|
|
|
66
92
|
insert_into_file(
|
|
67
93
|
model_file,
|
|
68
|
-
|
|
94
|
+
include_lines,
|
|
69
95
|
after: /class #{Regexp.escape(simple_class_name)} < .*\n/
|
|
70
96
|
)
|
|
71
97
|
end
|