responders 2.0.2 → 3.0.1
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 +5 -5
- data/CHANGELOG.md +48 -1
- data/MIT-LICENSE +2 -1
- data/README.md +115 -46
- data/lib/action_controller/respond_with.rb +44 -15
- data/lib/action_controller/responder.rb +30 -14
- data/lib/generators/rails/responders_controller_generator.rb +4 -26
- data/lib/generators/rails/templates/api_controller.rb.tt +51 -0
- data/lib/generators/rails/templates/{controller.rb → controller.rb.tt} +6 -4
- data/lib/generators/responders/install_generator.rb +10 -0
- data/lib/responders.rb +13 -17
- data/lib/responders/collection_responder.rb +2 -0
- data/lib/responders/controller_method.rb +7 -2
- data/lib/responders/flash_responder.rb +32 -18
- data/lib/responders/http_cache_responder.rb +3 -1
- data/lib/responders/location_responder.rb +3 -1
- data/lib/responders/version.rb +3 -1
- metadata +23 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 00a016ab308a0960fc75a6dc1d6f8b35b3165fe0edfef25cb3b898631c7c0454
|
4
|
+
data.tar.gz: bf658c0505d528307b5b61b9c1854fa76b50269c7ddedc27f7c3816e588c2a1f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 316cf7158bbfede88e505b1b2dfe25cf86ef873f678362da6062d5b4093849a190da2f730265021e7a3613f5a5bb1622553bc423d8850226ee5235083a9cf38b
|
7
|
+
data.tar.gz: 7aa5dbc3ef20b9c7ddafa0d8342067eaccfc2b50231eef76c00cf7c9a5e07703d449110ee4ec8dc4f3dcb9fa7c06472e0635cc3c41d05820a193c9f7445d14e7
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,50 @@
|
|
1
|
+
## 3.0.1
|
2
|
+
|
3
|
+
* Add support to Ruby 2.7
|
4
|
+
|
5
|
+
## 3.0.0
|
6
|
+
|
7
|
+
* Remove support for Rails 4.2
|
8
|
+
* Remove support for Ruby < 2.4
|
9
|
+
|
10
|
+
## 2.4.1
|
11
|
+
|
12
|
+
* Add support for Rails 6 beta
|
13
|
+
|
14
|
+
## 2.4.0
|
15
|
+
|
16
|
+
* `respond_with` now accepts a new kwargs called `:render` which goes straight to the `render`
|
17
|
+
call after an unsuccessful post request. Usefull if for example you need to render a template
|
18
|
+
which is outside of controller's path eg:
|
19
|
+
|
20
|
+
`respond_with resource, render: { template: 'path/to/template' }`
|
21
|
+
|
22
|
+
## 2.3.0
|
23
|
+
|
24
|
+
* `verify_request_format!` is aliased to `verify_requested_format!` now.
|
25
|
+
* Implementing the `interpolation_options` method on your controller is deprecated
|
26
|
+
in favor of naming it `flash_interpolation_options` instead.
|
27
|
+
|
28
|
+
## 2.2.0
|
29
|
+
|
30
|
+
* Added the `verify_request_format!` method, that can be used as a `before_action`
|
31
|
+
callback to prevent your actions from being invoked when the controller does
|
32
|
+
not respond to the request mime type, preventing the execution of complex
|
33
|
+
queries or creating/deleting records from your app.
|
34
|
+
|
35
|
+
## 2.1.2
|
36
|
+
|
37
|
+
* Fix rendering when using `ActionController::API`. (by @eLod)
|
38
|
+
* Added API controller template for the controller generator. (by @vestimir)
|
39
|
+
|
40
|
+
## 2.1.1
|
41
|
+
|
42
|
+
* Added support for Rails 5.
|
43
|
+
|
44
|
+
## 2.1.0
|
45
|
+
|
46
|
+
* No longer automatically set the responders generator as many projects may use this gem as a dependency. When upgrading, users will need to add `config.app_generators.scaffold_controller :responders_controller` to their application. The `responders:install` generator has been updated to automatically insert it in new applications
|
47
|
+
|
1
48
|
## 2.0.1
|
2
49
|
|
3
50
|
* Require `rails/railtie` explicitly before using it
|
@@ -8,7 +55,7 @@
|
|
8
55
|
|
9
56
|
* Import `respond_with` and class-level `respond_to` from Rails
|
10
57
|
* Support only Rails ~> 4.2
|
11
|
-
* `Responders::LocationResponder` is now included by
|
58
|
+
* `Responders::LocationResponder` is now included by the default responder (and therefore deprecated)
|
12
59
|
|
13
60
|
## 1.1.0
|
14
61
|
|
data/MIT-LICENSE
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
Copyright
|
1
|
+
Copyright (c) 2020 Rafael França, Carlos Antônio da Silva
|
2
|
+
Copyright 2009-2019 Plataformatec. http://plataformatec.com.br
|
2
3
|
|
3
4
|
Permission is hereby granted, free of charge, to any person obtaining
|
4
5
|
a copy of this software and associated documentation files (the
|
data/README.md
CHANGED
@@ -1,10 +1,25 @@
|
|
1
1
|
# Responders
|
2
2
|
|
3
|
-
[](http://badge.fury.io/rb/responders)
|
4
|
+
[](http://travis-ci.org/heartcombo/responders)
|
5
|
+
[](https://codeclimate.com/github/heartcombo/responders)
|
6
6
|
|
7
|
-
A set of responders modules to dry up your Rails
|
7
|
+
A set of responders modules to dry up your Rails app.
|
8
|
+
|
9
|
+
## Installation
|
10
|
+
|
11
|
+
Add the responders gem to your Gemfile:
|
12
|
+
|
13
|
+
gem "responders"
|
14
|
+
|
15
|
+
Update your bundle and run the install generator:
|
16
|
+
|
17
|
+
$ bundle install
|
18
|
+
$ rails g responders:install
|
19
|
+
|
20
|
+
If you are including this gem to support backwards compatibilty for responders in previous releases of Rails, you only need to include the gem and bundle.
|
21
|
+
|
22
|
+
$ bundle install
|
8
23
|
|
9
24
|
## Responders Types
|
10
25
|
|
@@ -60,15 +75,27 @@ You can also have embedded HTML. Just create a `_html` scope.
|
|
60
75
|
|
61
76
|
See also the `namespace_lookup` option to search the full hierarchy of possible keys.
|
62
77
|
|
78
|
+
### HttpCacheResponder
|
79
|
+
|
80
|
+
Automatically adds Last-Modified headers to API requests. This
|
81
|
+
allows clients to easily query the server if a resource changed and if the client tries
|
82
|
+
to retrieve a resource that has not been modified, it returns not_modified status.
|
83
|
+
|
84
|
+
### CollectionResponder
|
85
|
+
|
86
|
+
Makes your create and update action redirect to the collection on success.
|
87
|
+
|
63
88
|
### LocationResponder
|
64
89
|
|
65
90
|
This responder allows you to use callable objects as the redirect location.
|
66
91
|
Useful when you want to use the `respond_with` method with
|
67
92
|
a custom route that requires persisted objects, but the validation may fail.
|
68
93
|
|
94
|
+
Note: this responder is included by default, and doesn't need to be included
|
95
|
+
on the top of your controller (including it will issue a deprecation warning).
|
96
|
+
|
69
97
|
```ruby
|
70
98
|
class ThingsController < ApplicationController
|
71
|
-
responders :location, :flash
|
72
99
|
respond_to :html
|
73
100
|
|
74
101
|
def create
|
@@ -78,59 +105,48 @@ class ThingsController < ApplicationController
|
|
78
105
|
end
|
79
106
|
```
|
80
107
|
|
81
|
-
|
82
|
-
|
83
|
-
Automatically adds Last-Modified headers to API requests. This
|
84
|
-
allows clients to easily query the server if a resource changed and if the client tries
|
85
|
-
to retrieve a resource that has not been modified, it returns not_modified status.
|
86
|
-
|
87
|
-
### CollectionResponder
|
88
|
-
|
89
|
-
Makes your create and update action redirect to the collection on success.
|
108
|
+
**Dealing with namespaced routes**
|
90
109
|
|
91
|
-
|
110
|
+
In order for the LocationResponder to find the correct route helper for namespaced routes you need to pass the namespaces to `respond_with`:
|
92
111
|
|
93
|
-
|
112
|
+
```ruby
|
113
|
+
class Api::V1::ThingsController < ApplicationController
|
114
|
+
respond_to :json
|
94
115
|
|
95
|
-
|
96
|
-
|
116
|
+
# POST /api/v1/things
|
117
|
+
def create
|
118
|
+
@thing = Thing.create(thing_params)
|
119
|
+
respond_with :api, :v1, @thing
|
120
|
+
end
|
121
|
+
end
|
97
122
|
```
|
98
123
|
|
99
|
-
|
100
|
-
|
101
|
-
```ruby
|
102
|
-
gem 'responders'
|
103
|
-
```
|
124
|
+
## Configuring your own responder
|
104
125
|
|
105
|
-
Responders only provides a set of modules
|
106
|
-
responder.
|
126
|
+
Responders only provides a set of modules and to use them you have to create your own
|
127
|
+
responder. After you run the install command, the following responder will be
|
128
|
+
generated in your application:
|
107
129
|
|
108
130
|
```ruby
|
109
|
-
# lib/
|
110
|
-
class
|
131
|
+
# lib/application_responder.rb
|
132
|
+
class ApplicationResponder < ActionController::Responder
|
111
133
|
include Responders::FlashResponder
|
112
134
|
include Responders::HttpCacheResponder
|
113
135
|
end
|
114
136
|
```
|
115
137
|
|
116
|
-
|
138
|
+
Your application also needs to be configured to use it:
|
117
139
|
|
118
140
|
```ruby
|
119
141
|
# app/controllers/application_controller.rb
|
120
|
-
require "
|
142
|
+
require "application_responder"
|
121
143
|
|
122
144
|
class ApplicationController < ActionController::Base
|
123
|
-
self.responder =
|
145
|
+
self.responder = ApplicationResponder
|
124
146
|
respond_to :html
|
125
147
|
end
|
126
148
|
```
|
127
149
|
|
128
|
-
Or, for your convenience, just do:
|
129
|
-
|
130
|
-
```console
|
131
|
-
rails generate responders:install
|
132
|
-
```
|
133
|
-
|
134
150
|
## Controller method
|
135
151
|
|
136
152
|
This gem also includes the controller method `responders`, which allows you to cherry-pick which
|
@@ -144,7 +160,7 @@ end
|
|
144
160
|
|
145
161
|
## Interpolation Options
|
146
162
|
|
147
|
-
You can pass in extra interpolation options for the translation by adding an `
|
163
|
+
You can pass in extra interpolation options for the translation by adding an `flash_interpolation_options` method to your controller:
|
148
164
|
|
149
165
|
```ruby
|
150
166
|
class InvitationsController < ApplicationController
|
@@ -157,33 +173,86 @@ class InvitationsController < ApplicationController
|
|
157
173
|
|
158
174
|
private
|
159
175
|
|
160
|
-
def
|
176
|
+
def flash_interpolation_options
|
161
177
|
{ resource_name: @invitation.email }
|
162
178
|
end
|
163
179
|
end
|
164
180
|
```
|
165
181
|
|
166
|
-
Now you would see the message "
|
182
|
+
Now you would see the message `"name@example.com was successfully created"` instead of the default `"Invitation was successfully created."`
|
167
183
|
|
168
184
|
## Generator
|
169
185
|
|
170
186
|
This gem also includes a responders controller generator, so your scaffold can be customized
|
171
|
-
to use `respond_with` instead of default `respond_to` blocks.
|
172
|
-
|
187
|
+
to use `respond_with` instead of default `respond_to` blocks. From 2.1, you need to explicitly opt-in to use this generator by adding the following to your `config/application.rb`:
|
188
|
+
|
189
|
+
```ruby
|
190
|
+
config.app_generators.scaffold_controller :responders_controller
|
191
|
+
```
|
192
|
+
|
193
|
+
## Failure handling
|
194
|
+
|
195
|
+
Responders don't use `valid?` to check for errors in models to figure out if
|
196
|
+
the request was successful or not, and relies on your controllers to call
|
197
|
+
`save` or `create` to trigger the validations.
|
198
|
+
|
199
|
+
```ruby
|
200
|
+
def create
|
201
|
+
@widget = Widget.new(widget_params)
|
202
|
+
# @widget will be a valid record for responders, as we haven't called `save`
|
203
|
+
# on it, and will always redirect to the `widgets_path`.
|
204
|
+
respond_with @widget, location: -> { widgets_path }
|
205
|
+
end
|
206
|
+
```
|
207
|
+
|
208
|
+
Responders will check if the `errors` object in your model is empty or not. Take
|
209
|
+
this in consideration when implementing different actions or writing test
|
210
|
+
assertions on this behavior for your controllers.
|
211
|
+
|
212
|
+
```ruby
|
213
|
+
def create
|
214
|
+
@widget = Widget.new(widget_params)
|
215
|
+
@widget.errors.add(:base, :invalid)
|
216
|
+
# `respond_with` will render the `new` template again.
|
217
|
+
respond_with @widget
|
218
|
+
end
|
219
|
+
```
|
220
|
+
|
221
|
+
## Verifying request formats
|
222
|
+
|
223
|
+
`respond_with` will raise an `ActionController::UnknownFormat` if the request
|
224
|
+
MIME type was not configured through the class level `respond_to`, but the
|
225
|
+
action will still be executed and any side effects (like creating a new record)
|
226
|
+
will still occur. To raise the `UnknownFormat` exception before your action
|
227
|
+
is invoked you can set the `verify_requested_format!` method as a `before_action`
|
228
|
+
on your controller.
|
229
|
+
|
230
|
+
```ruby
|
231
|
+
class WidgetsController < ApplicationController
|
232
|
+
respond_to :json
|
233
|
+
before_action :verify_requested_format!
|
234
|
+
|
235
|
+
# POST /widgets.html won't reach the `create` action.
|
236
|
+
def create
|
237
|
+
widget = Widget.create(widget_params)
|
238
|
+
respond_with widget
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
```
|
173
243
|
|
174
244
|
## Examples
|
175
245
|
|
176
|
-
Want more examples ? Check out
|
246
|
+
Want more examples ? Check out these blog posts:
|
177
247
|
|
178
|
-
* [One in Three: Inherited Resources, Has Scope and Responders](http://blog.plataformatec.com.br/2009/12/one-in-three-inherited-resources-has-scope-and-responders/)
|
179
248
|
* [Embracing REST with mind, body and soul](http://blog.plataformatec.com.br/2009/08/embracing-rest-with-mind-body-and-soul/)
|
180
249
|
* [Three reasons to love ActionController::Responder](http://weblog.rubyonrails.org/2009/8/31/three-reasons-love-responder/)
|
181
|
-
* [My five favorite things about Rails 3](http://www.engineyard.com/blog/2009/my-five-favorite-things-about-rails-3
|
250
|
+
* [My five favorite things about Rails 3](http://www.engineyard.com/blog/2009/my-five-favorite-things-about-rails-3)
|
182
251
|
|
183
252
|
## Bugs and Feedback
|
184
253
|
|
185
254
|
If you discover any bugs or want to drop a line, feel free to create an issue on GitHub.
|
186
255
|
|
187
|
-
http://github.com/
|
256
|
+
http://github.com/heartcombo/responders/issues
|
188
257
|
|
189
|
-
MIT License. Copyright
|
258
|
+
MIT License. Copyright 2020 Rafael França, Carlos Antônio da Silva. Copyright 2009-2019 Plataformatec.
|
@@ -1,5 +1,7 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/array/extract_options"
|
4
|
+
require "action_controller/metal/mime_responds"
|
3
5
|
|
4
6
|
module ActionController #:nodoc:
|
5
7
|
module RespondWith
|
@@ -37,17 +39,17 @@ module ActionController #:nodoc:
|
|
37
39
|
def respond_to(*mimes)
|
38
40
|
options = mimes.extract_options!
|
39
41
|
|
40
|
-
only_actions = Array(options.delete(:only)).map(&:
|
41
|
-
except_actions = Array(options.delete(:except)).map(&:
|
42
|
+
only_actions = Array(options.delete(:only)).map(&:to_sym)
|
43
|
+
except_actions = Array(options.delete(:except)).map(&:to_sym)
|
42
44
|
|
43
|
-
|
45
|
+
hash = mimes_for_respond_to.dup
|
44
46
|
mimes.each do |mime|
|
45
47
|
mime = mime.to_sym
|
46
|
-
|
47
|
-
|
48
|
-
|
48
|
+
hash[mime] = {}
|
49
|
+
hash[mime][:only] = only_actions unless only_actions.empty?
|
50
|
+
hash[mime][:except] = except_actions unless except_actions.empty?
|
49
51
|
end
|
50
|
-
self.mimes_for_respond_to =
|
52
|
+
self.mimes_for_respond_to = hash.freeze
|
51
53
|
end
|
52
54
|
|
53
55
|
# Clear all mime types in <tt>respond_to</tt>.
|
@@ -175,26 +177,34 @@ module ActionController #:nodoc:
|
|
175
177
|
# Also, a hash passed to +respond_with+ immediately after the specified
|
176
178
|
# resource(s) is interpreted as a set of options relevant to all
|
177
179
|
# formats. Any option accepted by +render+ can be used, e.g.
|
180
|
+
#
|
178
181
|
# respond_with @people, status: 200
|
182
|
+
#
|
179
183
|
# However, note that these options are ignored after an unsuccessful attempt
|
180
184
|
# to save a resource, e.g. when automatically rendering <tt>:new</tt>
|
181
185
|
# after a post request.
|
182
186
|
#
|
183
|
-
#
|
187
|
+
# Three additional options are relevant specifically to +respond_with+ -
|
184
188
|
# 1. <tt>:location</tt> - overwrites the default redirect location used after
|
185
189
|
# a successful html +post+ request.
|
186
190
|
# 2. <tt>:action</tt> - overwrites the default render action used after an
|
187
191
|
# unsuccessful html +post+ request.
|
192
|
+
# 3. <tt>:render</tt> - allows to pass any options directly to the <tt>:render<tt/>
|
193
|
+
# call after unsuccessful html +post+ request. Useful if for example you
|
194
|
+
# need to render a template which is outside of controller's path or you
|
195
|
+
# want to override the default http <tt>:status</tt> code, e.g.
|
196
|
+
#
|
197
|
+
# respond_with(resource, render: { template: 'path/to/template', status: 422 })
|
188
198
|
def respond_with(*resources, &block)
|
189
199
|
if self.class.mimes_for_respond_to.empty?
|
190
200
|
raise "In order to use respond_with, first you need to declare the " \
|
191
201
|
"formats your controller responds to in the class level."
|
192
202
|
end
|
193
203
|
|
194
|
-
mimes = collect_mimes_from_class_level
|
204
|
+
mimes = collect_mimes_from_class_level
|
195
205
|
collector = ActionController::MimeResponds::Collector.new(mimes, request.variant)
|
196
206
|
block.call(collector) if block_given?
|
197
|
-
|
207
|
+
|
198
208
|
if format = collector.negotiate_format(request)
|
199
209
|
_process_format(format)
|
200
210
|
options = resources.size == 1 ? {} : resources.extract_options!
|
@@ -206,12 +216,31 @@ module ActionController #:nodoc:
|
|
206
216
|
end
|
207
217
|
end
|
208
218
|
|
209
|
-
|
219
|
+
protected
|
220
|
+
|
221
|
+
# Before action callback that can be used to prevent requests that do not
|
222
|
+
# match the mime types defined through <tt>respond_to</tt> from being executed.
|
223
|
+
#
|
224
|
+
# class PeopleController < ApplicationController
|
225
|
+
# respond_to :html, :xml, :json
|
226
|
+
#
|
227
|
+
# before_action :verify_requested_format!
|
228
|
+
# end
|
229
|
+
def verify_requested_format!
|
230
|
+
mimes = collect_mimes_from_class_level
|
231
|
+
collector = ActionController::MimeResponds::Collector.new(mimes, request.variant)
|
232
|
+
|
233
|
+
unless collector.negotiate_format(request)
|
234
|
+
raise ActionController::UnknownFormat
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
alias :verify_request_format! :verify_requested_format!
|
210
239
|
|
211
240
|
# Collect mimes declared in the class method respond_to valid for the
|
212
241
|
# current action.
|
213
242
|
def collect_mimes_from_class_level #:nodoc:
|
214
|
-
action = action_name.
|
243
|
+
action = action_name.to_sym
|
215
244
|
|
216
245
|
self.class.mimes_for_respond_to.keys.select do |mime|
|
217
246
|
config = self.class.mimes_for_respond_to[mime]
|
@@ -226,4 +255,4 @@ module ActionController #:nodoc:
|
|
226
255
|
end
|
227
256
|
end
|
228
257
|
end
|
229
|
-
end
|
258
|
+
end
|
@@ -1,4 +1,6 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/json"
|
2
4
|
|
3
5
|
module ActionController #:nodoc:
|
4
6
|
# Responsible for exposing a resource to different mime requests,
|
@@ -121,12 +123,12 @@ module ActionController #:nodoc:
|
|
121
123
|
attr_reader :controller, :request, :format, :resource, :resources, :options
|
122
124
|
|
123
125
|
DEFAULT_ACTIONS_FOR_VERBS = {
|
124
|
-
:
|
125
|
-
:
|
126
|
-
:
|
126
|
+
post: :new,
|
127
|
+
patch: :edit,
|
128
|
+
put: :edit
|
127
129
|
}
|
128
130
|
|
129
|
-
def initialize(controller, resources, options={})
|
131
|
+
def initialize(controller, resources, options = {})
|
130
132
|
@controller = controller
|
131
133
|
@request = @controller.request
|
132
134
|
@format = @controller.formats.first
|
@@ -142,8 +144,8 @@ module ActionController #:nodoc:
|
|
142
144
|
end
|
143
145
|
end
|
144
146
|
|
145
|
-
delegate :head, :render, :redirect_to, :
|
146
|
-
delegate :get?, :post?, :patch?, :put?, :delete?, :
|
147
|
+
delegate :head, :render, :redirect_to, to: :controller
|
148
|
+
delegate :get?, :post?, :patch?, :put?, :delete?, to: :request
|
147
149
|
|
148
150
|
# Undefine :to_json and :to_yaml since it's defined on Object
|
149
151
|
undef_method(:to_json) if method_defined?(:to_json)
|
@@ -182,10 +184,12 @@ module ActionController #:nodoc:
|
|
182
184
|
# responds to :to_format and display it.
|
183
185
|
#
|
184
186
|
def to_format
|
185
|
-
if get?
|
187
|
+
if !get? && has_errors? && !response_overridden?
|
188
|
+
display_errors
|
189
|
+
elsif has_view_rendering? || response_overridden?
|
186
190
|
default_render
|
187
191
|
else
|
188
|
-
|
192
|
+
api_behavior
|
189
193
|
end
|
190
194
|
rescue ActionView::MissingTemplate
|
191
195
|
api_behavior
|
@@ -198,7 +202,7 @@ module ActionController #:nodoc:
|
|
198
202
|
if get?
|
199
203
|
raise error
|
200
204
|
elsif has_errors? && default_action
|
201
|
-
render
|
205
|
+
render rendering_options
|
202
206
|
else
|
203
207
|
redirect_to navigation_location
|
204
208
|
end
|
@@ -211,7 +215,7 @@ module ActionController #:nodoc:
|
|
211
215
|
if get?
|
212
216
|
display resource
|
213
217
|
elsif post?
|
214
|
-
display resource, :
|
218
|
+
display resource, status: :created, location: api_location
|
215
219
|
else
|
216
220
|
head :no_content
|
217
221
|
end
|
@@ -233,7 +237,7 @@ module ActionController #:nodoc:
|
|
233
237
|
if @default_response
|
234
238
|
@default_response.call(options)
|
235
239
|
else
|
236
|
-
controller.
|
240
|
+
controller.render(options)
|
237
241
|
end
|
238
242
|
end
|
239
243
|
|
@@ -254,7 +258,7 @@ module ActionController #:nodoc:
|
|
254
258
|
#
|
255
259
|
# render xml: @user, status: :created
|
256
260
|
#
|
257
|
-
def display(resource, given_options={})
|
261
|
+
def display(resource, given_options = {})
|
258
262
|
controller.render given_options.merge!(options).merge!(format => resource)
|
259
263
|
end
|
260
264
|
|
@@ -273,6 +277,10 @@ module ActionController #:nodoc:
|
|
273
277
|
Renderers::RENDERERS.include?(format)
|
274
278
|
end
|
275
279
|
|
280
|
+
def has_view_rendering?
|
281
|
+
controller.class.include? ActionView::Rendering
|
282
|
+
end
|
283
|
+
|
276
284
|
# By default, render the <code>:edit</code> action for HTML requests with errors, unless
|
277
285
|
# the verb was POST.
|
278
286
|
#
|
@@ -285,11 +293,19 @@ module ActionController #:nodoc:
|
|
285
293
|
end
|
286
294
|
|
287
295
|
def json_resource_errors
|
288
|
-
{:
|
296
|
+
{ errors: resource.errors }
|
289
297
|
end
|
290
298
|
|
291
299
|
def response_overridden?
|
292
300
|
@default_response.present?
|
293
301
|
end
|
302
|
+
|
303
|
+
def rendering_options
|
304
|
+
if options[:render]
|
305
|
+
options[:render]
|
306
|
+
else
|
307
|
+
{ action: default_action }
|
308
|
+
end
|
309
|
+
end
|
294
310
|
end
|
295
311
|
end
|
@@ -1,4 +1,6 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rails/generators/rails/scaffold_controller/scaffold_controller_generator"
|
2
4
|
|
3
5
|
module Rails
|
4
6
|
module Generators
|
@@ -15,32 +17,8 @@ module Rails
|
|
15
17
|
end
|
16
18
|
end
|
17
19
|
|
18
|
-
def orm_instance_update(params)
|
19
|
-
if orm_instance.respond_to?(:update)
|
20
|
-
orm_instance.update params
|
21
|
-
else
|
22
|
-
orm_instance.update_attributes params
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
def controller_before_filter
|
27
|
-
if ActionController::Base.respond_to?(:before_action)
|
28
|
-
"before_action"
|
29
|
-
else
|
30
|
-
"before_filter"
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
20
|
def attributes_params
|
35
|
-
|
36
|
-
"#{file_name}_params"
|
37
|
-
else
|
38
|
-
"params[:#{file_name}]"
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
def strong_parameters_defined?
|
43
|
-
defined?(ActionController::StrongParameters)
|
21
|
+
"#{singular_table_name}_params"
|
44
22
|
end
|
45
23
|
end
|
46
24
|
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
<% if namespaced? -%>
|
2
|
+
require_dependency "<%= namespaced_file_path %>/application_controller"
|
3
|
+
|
4
|
+
<% end -%>
|
5
|
+
<% module_namespacing do -%>
|
6
|
+
class <%= controller_class_name %>Controller < ApplicationController
|
7
|
+
before_action :set_<%= singular_table_name %>, only: [:show, :update, :destroy]
|
8
|
+
|
9
|
+
respond_to :json
|
10
|
+
|
11
|
+
<% unless options[:singleton] -%>
|
12
|
+
def index
|
13
|
+
@<%= plural_table_name %> = <%= orm_class.all(class_name) %>
|
14
|
+
respond_with(@<%= plural_table_name %>)
|
15
|
+
end
|
16
|
+
<% end -%>
|
17
|
+
|
18
|
+
def show
|
19
|
+
respond_with(@<%= singular_table_name %>)
|
20
|
+
end
|
21
|
+
|
22
|
+
def create
|
23
|
+
@<%= singular_table_name %> = <%= orm_class.build(class_name, attributes_params) %>
|
24
|
+
<%= "flash[:notice] = '#{class_name} was successfully created.' if " if flash? %>@<%= orm_instance.save %>
|
25
|
+
respond_with(@<%= singular_table_name %>)
|
26
|
+
end
|
27
|
+
|
28
|
+
def update
|
29
|
+
<%= "flash[:notice] = '#{class_name} was successfully updated.' if " if flash? %>@<%= orm_instance.update(attributes_params) %>
|
30
|
+
respond_with(@<%= singular_table_name %>)
|
31
|
+
end
|
32
|
+
|
33
|
+
def destroy
|
34
|
+
@<%= orm_instance.destroy %>
|
35
|
+
respond_with(@<%= singular_table_name %>)
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
def set_<%= singular_table_name %>
|
40
|
+
@<%= singular_table_name %> = <%= orm_class.find(class_name, "params[:id]") %>
|
41
|
+
end
|
42
|
+
|
43
|
+
def <%= "#{singular_table_name}_params" %>
|
44
|
+
<%- if attributes_names.empty? -%>
|
45
|
+
params[:<%= singular_table_name %>]
|
46
|
+
<%- else -%>
|
47
|
+
params.require(:<%= singular_table_name %>).permit(<%= attributes_names.map { |name| ":#{name}" }.join(', ') %>)
|
48
|
+
<%- end -%>
|
49
|
+
end
|
50
|
+
end
|
51
|
+
<% end -%>
|
@@ -1,6 +1,10 @@
|
|
1
|
+
<% if namespaced? -%>
|
2
|
+
require_dependency "<%= namespaced_file_path %>/application_controller"
|
3
|
+
|
4
|
+
<% end -%>
|
1
5
|
<% module_namespacing do -%>
|
2
6
|
class <%= controller_class_name %>Controller < ApplicationController
|
3
|
-
|
7
|
+
before_action :set_<%= singular_table_name %>, only: [:show, :edit, :update, :destroy]
|
4
8
|
|
5
9
|
respond_to :html
|
6
10
|
|
@@ -30,7 +34,7 @@ class <%= controller_class_name %>Controller < ApplicationController
|
|
30
34
|
end
|
31
35
|
|
32
36
|
def update
|
33
|
-
<%= "flash[:notice] = '#{class_name} was successfully updated.' if " if flash? %>@<%=
|
37
|
+
<%= "flash[:notice] = '#{class_name} was successfully updated.' if " if flash? %>@<%= orm_instance.update(attributes_params) %>
|
34
38
|
respond_with(@<%= singular_table_name %>)
|
35
39
|
end
|
36
40
|
|
@@ -43,7 +47,6 @@ class <%= controller_class_name %>Controller < ApplicationController
|
|
43
47
|
def set_<%= singular_table_name %>
|
44
48
|
@<%= singular_table_name %> = <%= orm_class.find(class_name, "params[:id]") %>
|
45
49
|
end
|
46
|
-
<%- if strong_parameters_defined? -%>
|
47
50
|
|
48
51
|
def <%= "#{singular_table_name}_params" %>
|
49
52
|
<%- if attributes_names.empty? -%>
|
@@ -52,6 +55,5 @@ class <%= controller_class_name %>Controller < ApplicationController
|
|
52
55
|
params.require(:<%= singular_table_name %>).permit(<%= attributes_names.map { |name| ":#{name}" }.join(', ') %>)
|
53
56
|
<%- end -%>
|
54
57
|
end
|
55
|
-
<%- end -%>
|
56
58
|
end
|
57
59
|
<% end -%>
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Responders
|
2
4
|
module Generators
|
3
5
|
class InstallGenerator < Rails::Generators::Base
|
@@ -18,6 +20,14 @@ end
|
|
18
20
|
RUBY
|
19
21
|
end
|
20
22
|
|
23
|
+
def update_application
|
24
|
+
inject_into_class "config/application.rb", "Application", <<-RUBY
|
25
|
+
# Use the responders controller from the responders gem
|
26
|
+
config.app_generators.scaffold_controller :responders_controller
|
27
|
+
|
28
|
+
RUBY
|
29
|
+
end
|
30
|
+
|
21
31
|
def update_application_controller
|
22
32
|
prepend_file "app/controllers/application_controller.rb", %{require "application_responder"\n\n}
|
23
33
|
inject_into_class "app/controllers/application_controller.rb", "ApplicationController", <<-RUBY
|
data/lib/responders.rb
CHANGED
@@ -1,33 +1,29 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "action_controller"
|
4
|
+
require "rails/railtie"
|
3
5
|
|
4
6
|
module ActionController
|
5
|
-
autoload :Responder,
|
6
|
-
autoload :RespondWith,
|
7
|
+
autoload :Responder, "action_controller/responder"
|
8
|
+
autoload :RespondWith, "action_controller/respond_with"
|
7
9
|
end
|
8
10
|
|
9
11
|
module Responders
|
10
|
-
autoload :FlashResponder,
|
11
|
-
autoload :HttpCacheResponder,
|
12
|
-
autoload :CollectionResponder,
|
13
|
-
autoload :LocationResponder,
|
12
|
+
autoload :FlashResponder, "responders/flash_responder"
|
13
|
+
autoload :HttpCacheResponder, "responders/http_cache_responder"
|
14
|
+
autoload :CollectionResponder, "responders/collection_responder"
|
15
|
+
autoload :LocationResponder, "responders/location_responder"
|
14
16
|
|
15
|
-
require
|
17
|
+
require "responders/controller_method"
|
16
18
|
|
17
19
|
class Railtie < ::Rails::Railtie
|
18
20
|
config.responders = ActiveSupport::OrderedOptions.new
|
19
21
|
config.responders.flash_keys = [:notice, :alert]
|
20
22
|
config.responders.namespace_lookup = false
|
21
23
|
|
22
|
-
if config.respond_to?(:app_generators)
|
23
|
-
config.app_generators.scaffold_controller = :responders_controller
|
24
|
-
else
|
25
|
-
config.generators.scaffold_controller = :responders_controller
|
26
|
-
end
|
27
|
-
|
28
24
|
# Add load paths straight to I18n, so engines and application can overwrite it.
|
29
|
-
require
|
30
|
-
I18n.load_path << File.expand_path(
|
25
|
+
require "active_support/i18n"
|
26
|
+
I18n.load_path << File.expand_path("../responders/locales/en.yml", __FILE__)
|
31
27
|
|
32
28
|
initializer "responders.flash_responder" do |app|
|
33
29
|
Responders::FlashResponder.flash_keys = app.config.responders.flash_keys
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Responders
|
2
4
|
module ControllerMethod
|
3
5
|
# Adds the given responders to the current controller's responder, allowing you to cherry-pick
|
@@ -18,7 +20,8 @@ module Responders
|
|
18
20
|
#
|
19
21
|
def responders(*responders)
|
20
22
|
self.responder = responders.inject(Class.new(responder)) do |klass, responder|
|
21
|
-
responder =
|
23
|
+
responder = \
|
24
|
+
case responder
|
22
25
|
when Module
|
23
26
|
responder
|
24
27
|
when String, Symbol
|
@@ -34,4 +37,6 @@ module Responders
|
|
34
37
|
end
|
35
38
|
end
|
36
39
|
|
37
|
-
|
40
|
+
ActiveSupport.on_load(:action_controller) do
|
41
|
+
ActionController::Base.extend Responders::ControllerMethod
|
42
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Responders
|
2
4
|
# Responder to automatically set flash messages based on I18n API. It checks for
|
3
5
|
# message based on the current action, but also allows defaults to be set, using
|
@@ -33,9 +35,9 @@ module Responders
|
|
33
35
|
# notice: "Hooray! You just tuned your %{car_brand}!"
|
34
36
|
#
|
35
37
|
# Since :car_name is not available for interpolation by default, you have
|
36
|
-
# to overwrite
|
38
|
+
# to overwrite `flash_interpolation_options` in your controller.
|
37
39
|
#
|
38
|
-
# def
|
40
|
+
# def flash_interpolation_options
|
39
41
|
# { :car_brand => @car.brand }
|
40
42
|
# end
|
41
43
|
#
|
@@ -94,7 +96,7 @@ module Responders
|
|
94
96
|
ActionView::Helpers::TagHelper
|
95
97
|
)
|
96
98
|
|
97
|
-
def initialize(controller, resources, options={})
|
99
|
+
def initialize(controller, resources, options = {})
|
98
100
|
super
|
99
101
|
@flash = options.delete(:flash)
|
100
102
|
@notice = options.delete(:notice)
|
@@ -126,7 +128,7 @@ module Responders
|
|
126
128
|
return if controller.flash[status].present?
|
127
129
|
|
128
130
|
options = mount_i18n_options(status)
|
129
|
-
message = Responders::FlashResponder.helper.t options[:default].shift, options
|
131
|
+
message = Responders::FlashResponder.helper.t options[:default].shift, **options
|
130
132
|
set_flash(status, message)
|
131
133
|
end
|
132
134
|
|
@@ -147,34 +149,46 @@ module Responders
|
|
147
149
|
end
|
148
150
|
|
149
151
|
def mount_i18n_options(status) #:nodoc:
|
150
|
-
resource_name = if resource.class.respond_to?(:model_name)
|
151
|
-
resource.class.model_name.human
|
152
|
-
else
|
153
|
-
resource.class.name.underscore.humanize
|
154
|
-
end
|
155
|
-
|
156
152
|
options = {
|
157
|
-
:
|
158
|
-
:
|
159
|
-
:
|
153
|
+
default: flash_defaults_by_namespace(status),
|
154
|
+
resource_name: resource_name,
|
155
|
+
downcase_resource_name: resource_name.downcase
|
160
156
|
}
|
161
157
|
|
162
|
-
|
163
|
-
|
158
|
+
controller_options = controller_interpolation_options
|
159
|
+
if controller_options
|
160
|
+
options.merge!(controller_options)
|
164
161
|
end
|
165
162
|
|
166
163
|
options
|
167
164
|
end
|
168
165
|
|
166
|
+
def controller_interpolation_options
|
167
|
+
if controller.respond_to?(:flash_interpolation_options, true)
|
168
|
+
controller.send(:flash_interpolation_options)
|
169
|
+
elsif controller.respond_to?(:interpolation_options, true)
|
170
|
+
ActiveSupport::Deprecation.warn("[responders] `#{controller.class}#interpolation_options` is deprecated, please rename it to `flash_interpolation_options`.")
|
171
|
+
controller.send(:interpolation_options)
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
def resource_name
|
176
|
+
if resource.class.respond_to?(:model_name)
|
177
|
+
resource.class.model_name.human
|
178
|
+
else
|
179
|
+
resource.class.name.underscore.humanize
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
169
183
|
def flash_defaults_by_namespace(status) #:nodoc:
|
170
184
|
defaults = []
|
171
|
-
slices = controller.controller_path.split(
|
185
|
+
slices = controller.controller_path.split("/")
|
172
186
|
lookup = Responders::FlashResponder.namespace_lookup
|
173
187
|
|
174
188
|
begin
|
175
|
-
controller_scope = :"flash.#{slices.fill(controller.controller_name, -1).join(
|
189
|
+
controller_scope = :"flash.#{slices.fill(controller.controller_name, -1).join(".")}.#{controller.action_name}.#{status}"
|
176
190
|
|
177
|
-
actions_scope = lookup ? slices.fill(
|
191
|
+
actions_scope = lookup ? slices.fill("actions", -1).join(".") : :actions
|
178
192
|
actions_scope = :"flash.#{actions_scope}.#{controller.action_name}.#{status}"
|
179
193
|
|
180
194
|
defaults << :"#{controller_scope}_html"
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Responders
|
2
4
|
# Set HTTP Last-Modified headers based on the given resource. It's used only
|
3
5
|
# on API behavior (to_format) and is useful for a client to check in the server
|
@@ -9,7 +11,7 @@ module Responders
|
|
9
11
|
# the digest of the body.
|
10
12
|
#
|
11
13
|
module HttpCacheResponder
|
12
|
-
def initialize(controller, resources, options={})
|
14
|
+
def initialize(controller, resources, options = {})
|
13
15
|
super
|
14
16
|
@http_cache = options.delete(:http_cache)
|
15
17
|
end
|
@@ -1,7 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Responders
|
2
4
|
module LocationResponder
|
3
5
|
def self.included(_base)
|
4
|
-
ActiveSupport::Deprecation.warn "Responders::LocationResponder is enabled by default, "
|
6
|
+
ActiveSupport::Deprecation.warn "Responders::LocationResponder is enabled by default, " \
|
5
7
|
"no need to include it", caller
|
6
8
|
end
|
7
9
|
end
|
data/lib/responders/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: responders
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- José Valim
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-05-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: railties
|
@@ -16,22 +16,30 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
20
|
-
- - "<"
|
21
|
-
- !ruby/object:Gem::Version
|
22
|
-
version: '5'
|
19
|
+
version: '5.0'
|
23
20
|
type: :runtime
|
24
21
|
prerelease: false
|
25
22
|
version_requirements: !ruby/object:Gem::Requirement
|
26
23
|
requirements:
|
27
24
|
- - ">="
|
28
25
|
- !ruby/object:Gem::Version
|
29
|
-
version:
|
30
|
-
|
26
|
+
version: '5.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: actionpack
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '5.0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
31
39
|
- !ruby/object:Gem::Version
|
32
|
-
version: '5'
|
40
|
+
version: '5.0'
|
33
41
|
description: A set of Rails responders to dry up your application
|
34
|
-
email:
|
42
|
+
email: heartcombo@googlegroups.com
|
35
43
|
executables: []
|
36
44
|
extensions: []
|
37
45
|
extra_rdoc_files: []
|
@@ -43,7 +51,8 @@ files:
|
|
43
51
|
- lib/action_controller/responder.rb
|
44
52
|
- lib/generators/rails/USAGE
|
45
53
|
- lib/generators/rails/responders_controller_generator.rb
|
46
|
-
- lib/generators/rails/templates/
|
54
|
+
- lib/generators/rails/templates/api_controller.rb.tt
|
55
|
+
- lib/generators/rails/templates/controller.rb.tt
|
47
56
|
- lib/generators/responders/install_generator.rb
|
48
57
|
- lib/responders.rb
|
49
58
|
- lib/responders/collection_responder.rb
|
@@ -53,7 +62,7 @@ files:
|
|
53
62
|
- lib/responders/locales/en.yml
|
54
63
|
- lib/responders/location_responder.rb
|
55
64
|
- lib/responders/version.rb
|
56
|
-
homepage:
|
65
|
+
homepage: https://github.com/heartcombo/responders
|
57
66
|
licenses:
|
58
67
|
- MIT
|
59
68
|
metadata: {}
|
@@ -65,15 +74,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
65
74
|
requirements:
|
66
75
|
- - ">="
|
67
76
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
77
|
+
version: 2.4.0
|
69
78
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
70
79
|
requirements:
|
71
80
|
- - ">="
|
72
81
|
- !ruby/object:Gem::Version
|
73
82
|
version: '0'
|
74
83
|
requirements: []
|
75
|
-
|
76
|
-
rubygems_version: 2.2.2
|
84
|
+
rubygems_version: 3.1.2
|
77
85
|
signing_key:
|
78
86
|
specification_version: 4
|
79
87
|
summary: A set of Rails responders to dry up your application
|