crudable-rails 1.4.0 → 1.5.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 (30) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +161 -1
  3. data/lib/crudable/rails/base.rb +9 -1
  4. data/lib/crudable/rails/engine.rb +4 -0
  5. data/lib/crudable/rails/generators/scaffold_controller_extension.rb +55 -0
  6. data/lib/crudable/rails/generators/scaffold_extension.rb +29 -0
  7. data/lib/crudable/rails/generators/turbo_forms_generator_option.rb +16 -0
  8. data/lib/crudable/rails/generators/turbo_forms_scaffold_extension.rb +44 -0
  9. data/lib/crudable/rails/installer.rb +35 -0
  10. data/lib/crudable/rails/version.rb +1 -1
  11. data/lib/crudable-rails.rb +5 -0
  12. data/lib/generators/crudable/controller/USAGE +23 -0
  13. data/lib/generators/crudable/controller/controller_generator.rb +19 -0
  14. data/lib/generators/crudable/controller_helpers.rb +58 -0
  15. data/lib/generators/crudable/install/USAGE +8 -0
  16. data/lib/generators/crudable/install/install_generator.rb +19 -0
  17. data/lib/generators/crudable/scaffold/USAGE +14 -7
  18. data/lib/generators/crudable/scaffold/scaffold_generator.rb +8 -24
  19. data/lib/generators/crudable/templates/crudable_controller.rb.tt +257 -0
  20. data/lib/generators/crudable/templates/turbo_forms/_form.html.erb.tt +37 -0
  21. data/lib/generators/crudable/templates/turbo_forms/edit.html.erb.tt +14 -0
  22. data/lib/generators/crudable/templates/turbo_forms/edit.turbo_stream.erb.tt +3 -0
  23. data/lib/generators/crudable/templates/turbo_forms/new.html.erb.tt +13 -0
  24. data/lib/generators/crudable/templates/turbo_forms/new.turbo_stream.erb.tt +3 -0
  25. data/lib/tasks/crudable_tasks.rake +12 -4
  26. metadata +21 -9
  27. data/lib/generators/crudable/scaffold/templates/crudable_controller.rb.tt +0 -164
  28. data/lib/generators/scaffold_controller/USAGE +0 -13
  29. data/lib/generators/scaffold_controller/scaffold_controller_generator.rb +0 -36
  30. data/lib/generators/scaffold_controller/templates/crudable_controller.rb.tt +0 -164
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6eb33d21180100aca344bcdc68bb1c170e28bff416b95c3bb4332fcb7c1eef16
4
- data.tar.gz: a08037ec9a25220ba87697becdc928bf78400240088fb1f4c5157730dbfae162
3
+ metadata.gz: '082ec216ec1a73916737ffc58f6db08819237176efcaceb3b8c3978b5d3667e7'
4
+ data.tar.gz: 4ff9fd3a946d9ee5bb2839d0c41b72eac71a5139f26b87d01c9a608c8fa9204a
5
5
  SHA512:
6
- metadata.gz: ec33c0349fa255e003542bd431b5a84ea4b49ca981713409f372655944158dc9656070499d67c915d6dfb70e635136f736310ce84522bfa4e268b94bfb879896
7
- data.tar.gz: 2226bedef0b794653978bfd8deab2302d2023909857de65bbec4e600df3a545a171a2c9575271a3a8ca1e6041f3fdec9b86fc1775dcf2dc6d65fd543057ccf84
6
+ metadata.gz: 894987edb86a9fd16948ea85009387f8872667bfa2b49b0852193a3277147ffa39186450dcd7632a0984881ca3fea5723e3a024d8516e1ffacea5f2d72a7d50b
7
+ data.tar.gz: 9b3cd6f17af0ef03e9e95186fac23a7fbfd9e9572d079a93c4e1886fc29b112348bc23f0d39476a5b91843c98781035781e4d81b8cf44e506053f1505de854f4
data/README.md CHANGED
@@ -30,12 +30,57 @@ Or install it yourself as:
30
30
  $ gem install crudable-rails
31
31
  ```
32
32
 
33
+ Then run the install generator in your Rails application:
34
+
35
+ ```bash
36
+ bin/rails generate crudable:install
37
+ ```
38
+
39
+ This sets `config.action_controller.raise_on_missing_callback_actions` to `true` in any environment file under `config/environments/` that currently sets it to `false`. Crudable controllers rely on `before_action` callbacks; enabling this setting helps catch invalid `only` / `except` options early in development and test.
40
+
41
+ You can also run the same step as a Rake task:
42
+
43
+ ```bash
44
+ bin/rails crudable:install
45
+ ```
46
+
33
47
  ## Usage
34
48
 
35
49
  ### Controller Setup
36
50
 
37
51
  To use crudable-rails in your controllers, call the `crudable` method.
38
52
 
53
+ ### Generators
54
+
55
+ The gem ships Rails generators to scaffold resources with a Crudable controller. Generated controllers include `crudable`, a `permitted_params` method, and commented examples of every override hook with its default implementation — uncomment and tailor as needed.
56
+
57
+ **Full scaffold** — model, migration, views, routes, tests, and a Crudable controller (same output as `rails generate scaffold`, but with a Crudable controller):
58
+
59
+ ```bash
60
+ bin/rails generate crudable:scaffold Post title:string body:text
61
+ bin/rails generate crudable:scaffold Post title:string body:text --turbo-forms
62
+ ```
63
+
64
+ With `--turbo-forms`, generated `new` and `edit` views wrap the `_form` partial in a `dom_id(record, :form)` target and add matching `new.turbo_stream.erb` / `edit.turbo_stream.erb` templates. Failed create/update actions rendered by crudable will replace that form partial with validation errors inline.
65
+
66
+ **Controller only** — when you already have a model and views, or want to wire up the controller yourself:
67
+
68
+ ```bash
69
+ bin/rails generate crudable:controller Post title:string body:text
70
+ ```
71
+
72
+ You can also pass `--crudable` to the built-in Rails generators:
73
+
74
+ ```bash
75
+ bin/rails generate scaffold Post title:string body:text --crudable
76
+ bin/rails generate scaffold Post title:string body:text --crudable --turbo-forms
77
+ bin/rails generate scaffold_controller Post title:string body:text --crudable
78
+ ```
79
+
80
+ Use `rails generate scaffold` without `--crudable` when you want the standard Rails scaffold controller.
81
+
82
+ Nested routing is supported automatically: when a parent `*_id` param is present and an association exists between the parent and resource, collections and member actions are scoped through the parent.
83
+
39
84
  ## Customizing CRUD Actions
40
85
 
41
86
  You can override the default behavior of CRUD actions by defining the following methods in your controller:
@@ -83,6 +128,103 @@ By default, Turbo Streams are supported for create, update, and destroy actions.
83
128
 
84
129
  This method should return the permitted parameters for the resource as an array. It's required to be defined on all controllers.
85
130
 
131
+ The example below uses a `Product` with a `has_many :product_sizes` association and `accepts_nested_attributes_for`:
132
+
133
+ ```ruby
134
+ # app/models/product.rb
135
+ class Product < ApplicationRecord
136
+ has_many :product_sizes
137
+ accepts_nested_attributes_for :product_sizes, allow_destroy: true
138
+ end
139
+
140
+ # app/controllers/products_controller.rb
141
+ class ProductsController < ApplicationController
142
+ crudable
143
+
144
+ private
145
+
146
+ def permitted_params
147
+ [:name, product_sizes_attributes: [[:id, :name, :_destroy]]]
148
+ end
149
+ end
150
+ ```
151
+
152
+ A typical request payload for create/update looks like:
153
+
154
+ ```json
155
+ {
156
+ "product": {
157
+ "name": "T-shirt",
158
+ "product_sizes_attributes": {
159
+ "0": { "name": "Small" },
160
+ "1": { "id": "42", "name": "Medium" },
161
+ "2": { "id": "43", "_destroy": "1" }
162
+ }
163
+ }
164
+ }
165
+ ```
166
+
167
+ For `has_many` nested attributes, Rails 8 `expect` requires **double array brackets** — an array wrapped in an array — to declare that each nested record is a hash (`[[:id, :name, :_destroy]]`). This form also works with `require.permit` on hash-style payloads from `fields_for` / `accepts_nested_attributes_for`, so the same `permitted_params` definition works on both Rails versions.
168
+
169
+ ### `param_method`
170
+
171
+ Controls how strong parameters are required and permitted in `resource_params`. On **Rails 8+**, the default is `:expect`, which uses `params.expect` to require and permit in a single step. On earlier Rails versions, it falls back to `:require` (`params.require(...).permit(...)`).
172
+
173
+ **Rails 8 (default — `:expect`)**
174
+
175
+ ```ruby
176
+ class ProductsController < ApplicationController
177
+ crudable
178
+
179
+ private
180
+
181
+ def permitted_params
182
+ [:name, product_sizes_attributes: [[:id, :name, :_destroy]]]
183
+ end
184
+ end
185
+
186
+ # resource_params is equivalent to:
187
+ # params.expect(product: [:name, product_sizes_attributes: [[:id, :name, :_destroy]]])
188
+ ```
189
+
190
+ **Rails 7 and earlier (default — `:require`)**
191
+
192
+ ```ruby
193
+ class ProductsController < ApplicationController
194
+ crudable
195
+
196
+ private
197
+
198
+ def permitted_params
199
+ [:name, product_sizes_attributes: [[:id, :name, :_destroy]]]
200
+ end
201
+ end
202
+
203
+ # resource_params is equivalent to:
204
+ # params.require(:product).permit(:name, product_sizes_attributes: [[:id, :name, :_destroy]])
205
+ ```
206
+
207
+ **Override to use `require` on Rails 8**
208
+
209
+ ```ruby
210
+ class ProductsController < ApplicationController
211
+ crudable
212
+
213
+ private
214
+
215
+ def param_method
216
+ :require
217
+ end
218
+
219
+ def permitted_params
220
+ [:name, product_sizes_attributes: [[:id, :name, :_destroy]]]
221
+ end
222
+ end
223
+
224
+ # resource_params is equivalent to:
225
+ # params.require(:product).permit(:name, product_sizes_attributes: [[:id, :name, :_destroy]])
226
+ ```
227
+
86
228
  ### Optional Private Methods
87
229
 
88
230
  The following private methods are available for use in your controllers:
@@ -179,7 +321,25 @@ end
179
321
 
180
322
  ### `(create|update)_params`
181
323
 
182
- These methods should return the permitted parameters for the resource as an array. They are optional and can be defined if create and update methods need different parameters allowed.
324
+ These methods delegate to `resource_params` by default. Override them when create and update actions need different permitted parameters for example, allowing new sizes on create but only updates and destroys on update:
325
+
326
+ ```ruby
327
+ class ProductsController < ApplicationController
328
+ crudable
329
+
330
+ private
331
+
332
+ def create_params
333
+ params.expect(product: [:name, product_sizes_attributes: [[:name]]])
334
+ end
335
+
336
+ def update_params
337
+ params.expect(product: [:name, product_sizes_attributes: [[:id, :name, :_destroy]]])
338
+ end
339
+ end
340
+ ```
341
+
342
+ See `param_method` and `permitted_params` for the default strong-parameter handling.
183
343
 
184
344
  ## Overriding `authorizable_resource` with a Namespace
185
345
 
@@ -335,8 +335,16 @@ module Crudable
335
335
  resource_params
336
336
  end
337
337
 
338
+ def param_method
339
+ @param_method ||= ActionController::Parameters.method_defined?(:expect) ? :expect : :require
340
+ end
341
+
338
342
  def resource_params
339
- params.require(resource_var_name).permit(*permitted_params)
343
+ if param_method == :expect
344
+ params.send(param_method, resource_var_name.to_sym => permitted_params)
345
+ else
346
+ params.send(param_method, resource_var_name).permit(*permitted_params)
347
+ end
340
348
  end
341
349
 
342
350
  def permitted_params
@@ -10,6 +10,10 @@ module Crudable
10
10
  initializer 'crudable-rails.deprecator' do |app|
11
11
  app.deprecators[:crudable_rails] = Crudable::Rails.deprecator
12
12
  end
13
+
14
+ initializer 'crudable-rails.generators' do
15
+ require_relative 'generators/scaffold_controller_extension'
16
+ end
13
17
  end
14
18
  end
15
19
  end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../../generators/crudable/controller_helpers'
4
+ require_relative 'turbo_forms_generator_option'
5
+
6
+ module Crudable
7
+ module Rails
8
+ module Generators
9
+ module ScaffoldControllerExtension
10
+ extend ActiveSupport::Concern
11
+
12
+ prepended do
13
+ include TurboFormsGeneratorOption
14
+ include ::Crudable::Generators::ControllerHelpers
15
+
16
+ class_option :crudable, type: :boolean, default: false,
17
+ desc: 'Generate with crudable controller'
18
+ end
19
+
20
+ def create_controller_files
21
+ return super unless options.crudable?
22
+
23
+ template 'crudable_controller.rb',
24
+ File.join('app/controllers', controller_class_path, "#{controller_file_name}_controller.rb")
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+
31
+ Rails.application.config.after_initialize do
32
+ require 'rails/generators'
33
+ require 'rails/generators/named_base'
34
+ require 'rails/generators/resource_helpers'
35
+ require 'rails/generators/erb/scaffold/scaffold_generator'
36
+ require 'rails/generators/rails/scaffold_controller/scaffold_controller_generator'
37
+ require 'rails/generators/rails/scaffold/scaffold_generator'
38
+ require_relative 'scaffold_extension'
39
+ require_relative 'turbo_forms_scaffold_extension'
40
+
41
+ unless Rails::Generators::ScaffoldControllerGenerator
42
+ .ancestors.include?(Crudable::Rails::Generators::ScaffoldControllerExtension)
43
+ Rails::Generators::ScaffoldControllerGenerator.prepend Crudable::Rails::Generators::ScaffoldControllerExtension
44
+ end
45
+
46
+ unless Rails::Generators::ScaffoldGenerator
47
+ .included_modules.include?(Crudable::Rails::Generators::ScaffoldExtension)
48
+ Rails::Generators::ScaffoldGenerator.include Crudable::Rails::Generators::ScaffoldExtension
49
+ end
50
+
51
+ unless Erb::Generators::ScaffoldGenerator
52
+ .ancestors.include?(Crudable::Rails::Generators::TurboFormsScaffoldExtension)
53
+ Erb::Generators::ScaffoldGenerator.prepend Crudable::Rails::Generators::TurboFormsScaffoldExtension
54
+ end
55
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'turbo_forms_generator_option'
4
+
5
+ module Crudable
6
+ module Rails
7
+ module Generators
8
+ module ScaffoldExtension
9
+ extend ActiveSupport::Concern
10
+
11
+ included do
12
+ include TurboFormsGeneratorOption
13
+ include ::Crudable::Generators::ControllerHelpers
14
+
15
+ class_option :crudable, type: :boolean, default: false,
16
+ desc: 'Generate with crudable controller'
17
+ end
18
+
19
+ def crudable_controller
20
+ return unless options.crudable?
21
+
22
+ template 'crudable_controller.rb',
23
+ File.join('app/controllers', controller_class_path, "#{controller_file_name}_controller.rb"),
24
+ force: true
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Crudable
4
+ module Rails
5
+ module Generators
6
+ module TurboFormsGeneratorOption
7
+ extend ActiveSupport::Concern
8
+
9
+ included do
10
+ class_option :turbo_forms, type: :boolean, default: false,
11
+ desc: 'Generate turbo stream form templates for new and edit actions'
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'turbo_forms_generator_option'
4
+ require_relative '../../../generators/crudable/controller_helpers'
5
+
6
+ module Crudable
7
+ module Rails
8
+ module Generators
9
+ module TurboFormsScaffoldExtension
10
+ extend ActiveSupport::Concern
11
+
12
+ prepended do
13
+ include TurboFormsGeneratorOption
14
+ include ::Crudable::Generators::ControllerHelpers
15
+ end
16
+
17
+ def copy_view_files
18
+ super
19
+ return unless options.turbo_forms?
20
+
21
+ copy_turbo_forms_view_files
22
+ end
23
+
24
+ private
25
+
26
+ def copy_turbo_forms_view_files
27
+ view_path = File.join('app/views', controller_file_path)
28
+
29
+ template 'turbo_forms/_form.html.erb',
30
+ File.join(view_path, '_form.html.erb'),
31
+ force: true
32
+
33
+ %w[new edit].each do |view|
34
+ template "turbo_forms/#{view}.html.erb",
35
+ File.join(view_path, "#{view}.html.erb"),
36
+ force: true
37
+ template "turbo_forms/#{view}.turbo_stream.erb",
38
+ File.join(view_path, "#{view}.turbo_stream.erb")
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Crudable
4
+ module Rails
5
+ module Installer
6
+ CALLBACK_ACTIONS_FALSE =
7
+ /config\.action_controller\.raise_on_missing_callback_actions\s*=\s*false/
8
+
9
+ module_function
10
+
11
+ def postinstall(root: ::Rails.root)
12
+ environments_path = root.join('config/environments')
13
+ return [] unless environments_path.directory?
14
+
15
+ environments_path.glob('*.rb').filter_map do |file|
16
+ update_raise_on_missing_callback_actions(file)
17
+ end
18
+ end
19
+
20
+ def update_raise_on_missing_callback_actions(file)
21
+ contents = file.read
22
+ return unless contents.match?(CALLBACK_ACTIONS_FALSE)
23
+
24
+ updated_contents = contents.gsub(
25
+ CALLBACK_ACTIONS_FALSE,
26
+ 'config.action_controller.raise_on_missing_callback_actions = true'
27
+ )
28
+ return if updated_contents == contents
29
+
30
+ file.write(updated_contents)
31
+ file.basename.to_s
32
+ end
33
+ end
34
+ end
35
+ end
@@ -3,6 +3,6 @@
3
3
  # Crudable Version
4
4
  module Crudable
5
5
  module Rails
6
- VERSION = '1.4.0'
6
+ VERSION = '1.5.0'
7
7
  end
8
8
  end
@@ -3,6 +3,7 @@
3
3
  require 'turbo-rails'
4
4
 
5
5
  require 'crudable/rails/version'
6
+ require 'crudable/rails/installer'
6
7
  require 'crudable/rails/engine'
7
8
  require 'crudable/rails/controller'
8
9
  require 'crudable/rails/base'
@@ -14,5 +15,9 @@ module Crudable
14
15
  def self.deprecator
15
16
  @deprecator ||= ActiveSupport::Deprecation.new('2.0', 'Crudable::Rails')
16
17
  end
18
+
19
+ def self.postinstall(**)
20
+ Installer.postinstall(**)
21
+ end
17
22
  end
18
23
  end
@@ -0,0 +1,23 @@
1
+ Description:
2
+ Generates a Crudable controller with documented override hooks.
3
+
4
+ Pass the model name, either CamelCased or under_scored. The controller name
5
+ is retrieved as a pluralized version of the model name.
6
+
7
+ To create a controller within a module, specify the model name as a path like
8
+ 'parent_module/controller_name'.
9
+
10
+ Example:
11
+ bin/rails generate crudable:controller Post title:string body:text
12
+
13
+ This will create:
14
+ Controller: app/controllers/posts_controller.rb
15
+
16
+ Notes:
17
+ The generated controller includes `crudable` and a `permitted_params` method.
18
+ All other customization hooks are included as commented examples with their
19
+ defaults. Uncomment and tailor as needed.
20
+
21
+ Nested routing is automatically supported: if a parent `*_id` param is present
22
+ and an association exists between the parent and resource, collections and
23
+ resources will be scoped through the parent.
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../controller_helpers'
4
+
5
+ module Crudable
6
+ class ControllerGenerator < ::Rails::Generators::NamedBase
7
+ include ::Rails::Generators::ResourceHelpers
8
+ include Crudable::Generators::ControllerHelpers
9
+
10
+ argument :attributes, type: :array, default: [], banner: 'field:type field:type'
11
+
12
+ check_class_collision suffix: 'Controller'
13
+
14
+ def create_controller_file
15
+ template 'crudable_controller.rb',
16
+ File.join('app/controllers', controller_class_path, "#{controller_file_name}_controller.rb")
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Crudable
4
+ module Generators
5
+ module ControllerHelpers
6
+ extend ActiveSupport::Concern
7
+
8
+ class_methods do
9
+ def crudable_template_root
10
+ @crudable_template_root ||= File.expand_path('templates', __dir__)
11
+ end
12
+ end
13
+
14
+ included do
15
+ source_paths << crudable_template_root
16
+ end
17
+
18
+ private
19
+
20
+ def permitted_params_list
21
+ attachments, others = attributes_names.partition { |name| attachments?(name) }
22
+ params = others.map { |name| ":#{name}" }
23
+ params += attachments.map { |name| "#{name}: []" }
24
+ params.join(', ')
25
+ end
26
+
27
+ def attachments?(name)
28
+ attribute = attributes.find { |attr| attr.name == name }
29
+ attribute&.attachments?
30
+ end
31
+
32
+ def reference_attributes
33
+ attributes.select { |attr| attr.respond_to?(:reference?) && attr.reference? }
34
+ end
35
+
36
+ def form_attributes
37
+ return attributes if reference_attributes.empty?
38
+
39
+ attributes.reject { |attr| attr.respond_to?(:reference?) && attr.reference? }
40
+ end
41
+
42
+ def form_with_model
43
+ segments = []
44
+ segments.concat(controller_class_path.map { |namespace| ":#{namespace}" }) if controller_class_path.any?
45
+
46
+ reference_attributes.each do |attribute|
47
+ segments << "@#{attribute.name}"
48
+ end
49
+
50
+ segments << "@#{singular_table_name}"
51
+
52
+ return segments.first if segments.size == 1
53
+
54
+ "[#{segments.join(', ')}]"
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,8 @@
1
+ Description:
2
+ Installs crudable-rails configuration in the host application.
3
+
4
+ Example:
5
+ bin/rails generate crudable:install
6
+
7
+ This will set config.action_controller.raise_on_missing_callback_actions
8
+ to true in any environment file that currently sets it to false.
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Crudable
4
+ module Generators
5
+ class InstallGenerator < ::Rails::Generators::Base
6
+ desc 'Install crudable-rails configuration'
7
+
8
+ def postinstall
9
+ updated = ::Crudable::Rails::Installer.postinstall
10
+
11
+ if updated.any?
12
+ say "Set raise_on_missing_callback_actions to true in: #{updated.join(', ')}", :green
13
+ else
14
+ say 'No environment files with raise_on_missing_callback_actions = false were found.', :yellow
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -1,13 +1,20 @@
1
1
  Description:
2
- Generates a Rails scaffold and replaces the generated controller with a Crudable controller.
2
+ Generates a full Rails scaffold (model, migration, views, routes, tests) with a
3
+ Crudable controller instead of the default scaffold controller.
4
+
5
+ Pass the model name, either CamelCased or under_scored, and optional attributes.
3
6
 
4
7
  Example:
5
- bin/rails generate crudable:scaffold Thing
8
+ bin/rails generate crudable:scaffold Post title:string body:text
9
+ bin/rails generate crudable:scaffold Post title:string body:text --turbo-forms
10
+
11
+ This will create the same files as `rails generate scaffold`, but the controller
12
+ will use `crudable` with documented override hooks.
6
13
 
7
- This will create:
8
- It will generate a rails scaffold with a Crudable controller.
14
+ With --turbo-forms, new and edit views wrap the form partial in a dom_id target
15
+ and generate matching turbo_stream templates for validation error responses.
9
16
 
10
17
  Notes:
11
- Nested routing is automatically supported: if a parent `*_id` param is present and an association
12
- exists between the parent and resource, collections and resources will be scoped through the parent.
13
- Override `use_parent_as_scope?` in your controller to disable parent scoping.
18
+ Nested routing is automatically supported: if a parent `*_id` param is present
19
+ and an association exists between the parent and resource, collections and
20
+ resources will be scoped through the parent.
@@ -1,32 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Crudable
4
- class ScaffoldGenerator < Rails::Generators::NamedBase
5
- include Rails::Generators::ResourceHelpers
6
-
7
- source_root File.expand_path('templates', __dir__)
8
-
9
- argument :attributes, type: :array, default: [], banner: 'field:type field:type'
3
+ require 'rails/generators/rails/scaffold/scaffold_generator'
4
+ require_relative '../controller_helpers'
10
5
 
11
- hook_for :scaffold_controller, in: :rails
6
+ module Crudable
7
+ class ScaffoldGenerator < ::Rails::Generators::ScaffoldGenerator
8
+ include Crudable::Generators::ControllerHelpers
12
9
 
13
- def crudable
10
+ def crudable_controller
14
11
  template 'crudable_controller.rb',
15
- File.join('app/controllers', controller_class_path, "#{controller_file_name}_controller.rb"), force: true
16
- end
17
-
18
- private
19
-
20
- def permitted_params
21
- attachments, others = attributes_names.partition { |name| attachments?(name) }
22
- params = others.map { |name| ":#{name}" }
23
- params += attachments.map { |name| "#{name}: []" }
24
- params.join(', ')
25
- end
26
-
27
- def attachments?(name)
28
- attribute = attributes.find { |attr| attr.name == name }
29
- attribute&.attachments?
12
+ File.join('app/controllers', controller_class_path, "#{controller_file_name}_controller.rb"),
13
+ force: true
30
14
  end
31
15
  end
32
16
  end