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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6e0af52a7399d45699c4b84d80cead588d71f37e255bfa324141d8a0033aa561
4
- data.tar.gz: 241b9957c4a166c010d78c5f1175b98bc802eb28f4757131fc69d1c1d4e24e2d
3
+ metadata.gz: 48198bd6f914066ca468eae2e95cb9dba85003d49532b1db28f8620db3c40b21
4
+ data.tar.gz: 7a3e542b82e0ff43691e3a988dad6e42f59fc51da0e460220e5481881eb55ba3
5
5
  SHA512:
6
- metadata.gz: 736b763f3dbf6508d97e14b934240b2420db7da18b5e0eda0fd1c6c987e76e26ff3c36ea6a0c3c9d03ed6bf89fef1be5ad631303d38978fc52df021d0c717002
7
- data.tar.gz: 32bb39ef9cdc30d2023986db40e487a36869555ba3ac02582bb8ba9d89622d1030ed4ce2f9be8b043cf2e521dac1f08f3c1805c4ef389a092c362b157952164d
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
- - **Default concerns, unchanged.** `Api::ModelName`/`RailsAdmin::ModelName` concern files
30
- are generated and `include`d into the model, exactly as `thecore_code_extension`'s
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
- add one by hand, following the `after_initialize` + `class_eval` pattern, only when a
35
- real custom action is needed.
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 default concerns are
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 and `include`d into the model, replicating
19
- # thecore_code_extension's addModel.js templates exactly (unchanged
20
- # by this ticket — see thecore_generators#3 / ADR 0001 in the thecore
21
- # repo).
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
- add_default_concerns
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 — per this ticket's
53
- # explicit "unchanged, still generated exactly as today" scope (that
54
- # removal is thecore_generators#6, gated on other work landing first).
55
- def add_default_concerns
56
- template "api_concern.rb", File.join("app/models/concerns/api", class_path, "#{file_name}.rb")
57
- template "rails_admin_concern.rb", File.join("app/models/concerns/rails_admin", class_path, "#{file_name}.rb")
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
- include_default_concerns_in_model
85
+ include_opted_in_concerns_in_model(include_lines) unless include_lines.empty?
60
86
  end
61
87
 
62
- def include_default_concerns_in_model
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
- " include Api::#{class_name}\n include RailsAdmin::#{class_name}\n",
94
+ include_lines,
69
95
  after: /class #{Regexp.escape(simple_class_name)} < .*\n/
70
96
  )
71
97
  end
@@ -1,3 +1,3 @@
1
1
  module ThecoreGenerators
2
- VERSION = "3.1.0"
2
+ VERSION = "3.2.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: thecore_generators
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.0
4
+ version: 3.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gabriele Tassoni