crudable-rails 1.1.0 → 1.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4df342f4a146959d7105623ff9e8f1874111a5c4873f8320db55ebd38adf110b
4
- data.tar.gz: 6ee3eac43181b657e960b993097100095339fe8f087fe2444781fea85112df56
3
+ metadata.gz: 99f925a26ed45caef1bc7192a910d67de0d25c6e8129dce513b16d828b96b500
4
+ data.tar.gz: 9c32e8484c889fd27dbbdae01c6da7eecfd40a10bc444219fdb763c689961e50
5
5
  SHA512:
6
- metadata.gz: 54f5a65182975013cf1a561dd97ca54180220ae98bbf9764c1c805aa64996e48d7e3d0c17f91e65fe8b2f9ee729da94272ac9191ab9afbaed5f0847e2168071b
7
- data.tar.gz: fe602265e19c2f9cc5186851ea4723f6078021a038d9576ab8775f55d25ea75041f7b740967a223123dac72edc3a82cf510d44ace36e7cf2d3d537ad671dcfba
6
+ metadata.gz: 3fddb792095a0eb01d247b64e4ce00fc5a89db2b98b12686eb17a4860667e9ee036ddfad4fc3cb01cc6467e96665c046adc6883386c6c613dc3496a15a614b9d
7
+ data.tar.gz: 14e0083dd324cf14aa527bcc08e604d9bf5cab4c9ccbb753a7360a3670a39f43aaa672860a00a54aa11253848c8dbe9a74f6811496fe957546075498e33126fa
data/README.md CHANGED
@@ -1,28 +1,186 @@
1
- # Crudable
2
- Short description and motivation.
1
+ # Crudable Rails
3
2
 
4
- ## Usage
5
- How to use my plugin.
3
+ `crudable-rails` is a Ruby on Rails gem that provides a set of helpers and modules to simplify the implementation of CRUD operations in Rails controllers.
4
+
5
+ It uses the following gems to enhance the functionality:
6
+
7
+ - `Pundit` for authorization
8
+ - `Kaminari` for pagination
9
+ - `FriendlyId` for friendly finders
10
+ - `HasScope` for filtering
11
+ - `Discard` for soft deletion
6
12
 
7
13
  ## Installation
14
+
8
15
  Add this line to your application's Gemfile:
9
16
 
10
17
  ```ruby
11
- gem "crudable"
18
+ gem "crudable-rails"
12
19
  ```
13
20
 
14
21
  And then execute:
22
+
15
23
  ```bash
16
- $ bundle
24
+ $ bundle install
17
25
  ```
18
26
 
19
27
  Or install it yourself as:
28
+
20
29
  ```bash
21
- $ gem install crudable
30
+ $ gem install crudable-rails
31
+ ```
32
+
33
+ ## Usage
34
+
35
+ ### Controller Setup
36
+
37
+ To use crudable-rails in your controllers, call the `crudable` method. You can also specify if the controller is nested by passing the `nested: true` option.
38
+
39
+ ```ruby
40
+ class ProductsController < ApplicationController
41
+ crudable
42
+ end
43
+
44
+ class ProductSizesController < ApplicationController
45
+ crudable nested: true
46
+ end
47
+ ```
48
+
49
+ ## Customizing CRUD Actions
50
+
51
+ You can override the default behavior of CRUD actions by defining the following methods in your controller:
52
+
53
+ - `before_authorize_create`
54
+ - `after_authorize_create`
55
+ - `on_successful_create`
56
+ - `on_successful_create_render`
57
+ - `on_failed_create_setup`
58
+ - `on_failed_create_render`
59
+ - `before_authorize_update`
60
+ - `after_authorize_update`
61
+ - `on_successful_update`
62
+ - `on_successful_update_render`
63
+ - `on_failed_update_setup`
64
+ - `on_failed_update_render`
65
+ - `on_successful_destroy_render`
66
+ - `on_failed_destroy_render`
67
+
68
+ For example:
69
+
70
+ ```ruby
71
+ class ProductsController < ApplicationController
72
+ include Crudable::Rails::Controller
73
+
74
+ crudable
75
+
76
+ def on_successful_create
77
+ # Custom behavior on successful create
78
+ end
79
+
80
+ def on_failed_create_render
81
+ respond_to do |format|
82
+ format.html { render :new, status: :unprocessable_entity }
83
+ end
84
+ end
85
+ end
86
+ ```
87
+
88
+ By default, Turbo Streams are supported for create, update, and destroy actions. If Turbo Streams are not available, the gem will fallback to rendering HTML responses. If you require support for other formats, you can override the default behavior by defining the appropriate methods in your controller.
89
+
90
+ ### Required Private Methods
91
+
92
+ ### `permitted_params`
93
+
94
+ This method should return the permitted parameters for the resource as an array. It's required to be defined on all controllers.
95
+
96
+ ### Optional Private Methods
97
+
98
+ The following private methods are available for use in your controllers:
99
+
100
+ ### `after_create_redirect_path`
101
+
102
+ This method should return the path to redirect to after a successful create. By default this will redirect to the namespaced index of the resource being created.
103
+
104
+ ### `after_create_notice`
105
+
106
+ This method should return the notice to display after a successful create. By default this will return a success message via i18n.
107
+
108
+ ### `after_update_redirect_path`
109
+
110
+ This method should return the path to redirect to after a successful update. By default this will redirect to the namespaced show path of the resource being updated.
111
+
112
+ ### `after_update_notice`
113
+
114
+ This method should return the notice to display after a successful update. By default this will return a success message via i18n.
115
+
116
+ ### `after_destroy_redirect_path`
117
+
118
+ This method should return the path to redirect to after a successful destroy. By default this will redirect to the namespaced index of the resource being destroyed.
119
+
120
+ ### `after_failed_destroy_redirect_path`
121
+
122
+ This method should return the path to redirect to after a failed destroy. Default: `after_destroy_redirect_path`.
123
+
124
+ ### `after_destroy_notice`
125
+
126
+ This method should return the notice to display after a successful destroy. By default this will return a success message via i18n.
127
+
128
+ ### `after_failed_destroy_alert`
129
+
130
+ This method should return the alert to display after a failed destroy. By default this will return an error message via i18n.
131
+
132
+ ### `discard?`
133
+
134
+ This method should return a boolean value to determine if the resource should be discarded. If it returns `false` the resource will be destroyed. Default: `false`.
135
+
136
+ ### `singleton?`
137
+
138
+ This method should return a boolean value to determine if the resource is a singleton. Default: `false`.
139
+
140
+ ### `finder_param`
141
+
142
+ This method should return the parameter used to find the resource. Default: `:id`.
143
+
144
+ ### `paginate_resource?`
145
+
146
+ This method should return a boolean value to determine if the resource should be paginated. Default: `true` if Kaminari is available, otherwise `false`.
147
+
148
+ ### `friendly_finders?`
149
+
150
+ This method should return a boolean value to determine if the resource should be found using friendly finders. Default: `true` if FriendlyId is available, otherwise `false`.
151
+
152
+ ### `skip_initialize_create?`
153
+
154
+ This method should return a boolean value to determine if the resource should be initialized on create. Default: `false`.
155
+
156
+ ### `(create|update)_params`
157
+
158
+ 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.
159
+
160
+ ## Overriding `authorizable_resource` with a Namespace
161
+
162
+ The `authorizable_resource` method can be overridden to customize the resource authorization logic, especially when dealing with namespaced resources. This method should return the resource that needs to be authorized.
163
+
164
+ For example, if you have a namespaced controller:
165
+
166
+ ```ruby
167
+ module Admin
168
+ class ProductsController < ApplicationController
169
+ crudable
170
+
171
+ private
172
+
173
+ def authorizable_resource
174
+ [:admin, @product]
175
+ end
176
+ end
177
+ end
22
178
  ```
23
179
 
24
180
  ## Contributing
25
- Contribution directions go here.
181
+
182
+ Bug reports and pull requests are welcome on GitHub at https://github.com/your-username/crudable-rails. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the code of conduct.
26
183
 
27
184
  ## License
185
+
28
186
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -27,9 +27,11 @@ module Crudable
27
27
 
28
28
  def create # rubocop:disable Metrics/MethodLength
29
29
  instance_variable_set("@#{resource_var_name}", resource_class.new(create_params)) unless skip_initialize_create?
30
- before_authorize_create
31
- authorize_resource
32
- after_authorize_create
30
+ if defined?(Pundit)
31
+ before_authorize_create
32
+ authorize_resource
33
+ after_authorize_create
34
+ end
33
35
  if instance_variable_get("@#{resource_var_name}").save
34
36
  on_successful_create
35
37
  on_successful_create_render
@@ -42,9 +44,11 @@ module Crudable
42
44
  def edit; end
43
45
 
44
46
  def update
45
- before_authorize_update
46
- authorize_resource
47
- after_authorize_update
47
+ if defined?(Pundit)
48
+ before_authorize_update
49
+ authorize_resource
50
+ after_authorize_update
51
+ end
48
52
  if instance_variable_get("@#{resource_var_name}").update update_params
49
53
  on_successful_update
50
54
  on_successful_update_render
@@ -55,10 +59,12 @@ module Crudable
55
59
  end
56
60
 
57
61
  def destroy
58
- authorize_resource(destroy_method)
62
+ authorize_resource(destroy_method) if defined?(Pundit)
59
63
  if instance_variable_get("@#{resource_var_name}").send(destroy_method)
64
+ on_successful_destroy
60
65
  on_successful_destroy_render
61
66
  else
67
+ on_failed_destroy
62
68
  on_failed_destroy_render
63
69
  end
64
70
  end
@@ -164,28 +170,40 @@ module Crudable
164
170
  t('crudable.not_destroyed', model_name: resource_class.model_name.human)
165
171
  end
166
172
 
167
- def on_successful_create; end
173
+ def on_successful_create
174
+ flash[:success] = after_create_notice
175
+ end
168
176
 
169
177
  def on_successful_create_render
170
- redirect_to after_create_redirect_path, success: after_create_notice
178
+ redirect_to after_create_redirect_path
171
179
  end
172
180
 
173
181
  def on_failed_create_setup; end
174
182
 
175
- def on_successful_update; end
183
+ def on_successful_update
184
+ flash[:success] = after_update_notice
185
+ end
176
186
 
177
187
  def on_successful_update_render
178
- redirect_to after_update_redirect_path, success: after_update_notice
188
+ redirect_to after_update_redirect_path
179
189
  end
180
190
 
181
191
  def on_failed_update_setup; end
182
192
 
193
+ def on_successful_destroy
194
+ flash[:success] = after_destroy_notice
195
+ end
196
+
197
+ def on_failed_destroy
198
+ flash[:alert] = after_failed_destroy_alert
199
+ end
200
+
183
201
  def on_successful_destroy_render
184
- redirect_to after_destroy_redirect_path, success: after_destroy_notice
202
+ redirect_to after_destroy_redirect_path
185
203
  end
186
204
 
187
205
  def on_failed_destroy_render
188
- redirect_to after_failed_destroy_redirect_path, alert: after_failed_destroy_alert
206
+ redirect_to after_failed_destroy_redirect_path
189
207
  end
190
208
 
191
209
  def before_authorize_create; end
@@ -209,6 +227,22 @@ module Crudable
209
227
  format.html { render :edit, status: :unprocessable_entity }
210
228
  end
211
229
  end
230
+
231
+ def create_params
232
+ resource_params
233
+ end
234
+
235
+ def update_params
236
+ resource_params
237
+ end
238
+
239
+ def resource_params
240
+ params.require(resource_var_name).permit(*permitted_params)
241
+ end
242
+
243
+ def permitted_params
244
+ raise NotImplementedError, 'You must implement permitted_params in your controller'
245
+ end
212
246
  end
213
247
  end
214
248
  end
@@ -62,7 +62,7 @@ module Crudable
62
62
  def resource_namespace
63
63
  namespaces = name.split('::')
64
64
  namespaces.pop
65
- namespaces.map { |n| n.downcase.to_sym }
65
+ namespaces.map { |n| n.underscore.to_sym }
66
66
  end
67
67
  end
68
68
  end
@@ -3,6 +3,6 @@
3
3
  # Crudable Version
4
4
  module Crudable
5
5
  module Rails
6
- VERSION = '1.1.0'
6
+ VERSION = '1.2'
7
7
  end
8
8
  end
@@ -1,3 +1,5 @@
1
+ require 'turbo-rails'
2
+
1
3
  require 'crudable/rails/version'
2
4
  require 'crudable/rails/engine'
3
5
  require 'crudable/rails/controller'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: crudable-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: '1.2'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tomislav Simnett
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-10-14 00:00:00.000000000 Z
11
+ date: 2024-11-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '7.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: turbo-rails
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '2.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '2.0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: rubocop
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -38,6 +52,20 @@ dependencies:
38
52
  - - ">="
39
53
  - !ruby/object:Gem::Version
40
54
  version: '1.50'
55
+ - !ruby/object:Gem::Dependency
56
+ name: mocha
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '2.6'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '2.6'
41
69
  description: CRUD operations for Rails controllers
42
70
  email:
43
71
  - tom@initforthe.com