responders 3.0.1 → 3.1.0

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: 00a016ab308a0960fc75a6dc1d6f8b35b3165fe0edfef25cb3b898631c7c0454
4
- data.tar.gz: bf658c0505d528307b5b61b9c1854fa76b50269c7ddedc27f7c3816e588c2a1f
3
+ metadata.gz: bbd11b54b7dff0d570ff0231c4947ef6c086e75eec2939a6b96d4ebb65bc40f1
4
+ data.tar.gz: 5f6df15df62211cdc47025a70f4037a493dc1d679aa2a6a5a834d90135b07de1
5
5
  SHA512:
6
- metadata.gz: 316cf7158bbfede88e505b1b2dfe25cf86ef873f678362da6062d5b4093849a190da2f730265021e7a3613f5a5bb1622553bc423d8850226ee5235083a9cf38b
7
- data.tar.gz: 7aa5dbc3ef20b9c7ddafa0d8342067eaccfc2b50231eef76c00cf7c9a5e07703d449110ee4ec8dc4f3dcb9fa7c06472e0635cc3c41d05820a193c9f7445d14e7
6
+ metadata.gz: 62f893c63385f0d2de498143a4bcf0dafde98ef920778e5115af3d7b14f2d4c7dcdae08712193db9543e205e9830e307758b702970fe2480e7ccc322e8a81c38
7
+ data.tar.gz: 888a7bae0e92cdbdd8037f5cbfde45d09ec23d528d783aa11ac436bf21992aae7c63252285161a42513fb9c7dbb1ab4abf45b6371cadebfe9efd05bb2175d8e7
data/CHANGELOG.md CHANGED
@@ -1,3 +1,14 @@
1
+ ## Unreleased
2
+
3
+
4
+ ## 3.1.0
5
+
6
+ * Add config `responders.redirect_status` to allow overriding the redirect code/status used in redirects. The default is `302 Found`, which matches Rails, but it allows to change responders to redirect with `303 See Other` for example, to make it more compatible with how Hotwire/Turbo expects redirects to work.
7
+ * Add config `responders.error_status` to allow overriding the status code used to respond to `HTML` or `JS` requests that have errors on the resource. The default is `200 OK`, but it allows to change the response to be `422 Unprocessable Entity` in such cases for example, which makes it more consistent with other statuses more commonly used in APIs (like JSON/XML), and works by default with Turbo/Hotwire which expects a 422 on form error HTML responses. Note that changing this may break your application if you're relying on the previous 2xx status to handle error cases.
8
+ * Add support for Ruby 3.0, 3.1, and 3.2, drop support for Ruby < 2.5.
9
+ * Add support for Rails 6.1 and 7.0, drop support for Rails < 5.2.
10
+ * Move CI to GitHub Actions.
11
+
1
12
  ## 3.0.1
2
13
 
3
14
  * Add support to Ruby 2.7
@@ -13,8 +24,8 @@
13
24
 
14
25
  ## 2.4.0
15
26
 
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
27
+ * `respond_with` now accepts a new kwarg called `:render` which goes straight to the `render`
28
+ call after an unsuccessful post request. Useful if for example you need to render a template
18
29
  which is outside of controller's path eg:
19
30
 
20
31
  `respond_with resource, render: { template: 'path/to/template' }`
data/MIT-LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2020 Rafael França, Carlos Antônio da Silva
1
+ Copyright (c) 2020-2022 Rafael França, Carlos Antônio da Silva
2
2
  Copyright 2009-2019 Plataformatec. http://plataformatec.com.br
3
3
 
4
4
  Permission is hereby granted, free of charge, to any person obtaining
data/README.md CHANGED
@@ -1,8 +1,6 @@
1
1
  # Responders
2
2
 
3
3
  [![Gem Version](https://fury-badge.herokuapp.com/rb/responders.svg)](http://badge.fury.io/rb/responders)
4
- [![Build Status](https://api.travis-ci.org/plataformatec/responders.svg?branch=master)](http://travis-ci.org/heartcombo/responders)
5
- [![Code Climate](https://codeclimate.com/github/plataformatec/responders.svg)](https://codeclimate.com/github/heartcombo/responders)
6
4
 
7
5
  A set of responders modules to dry up your Rails app.
8
6
 
@@ -213,7 +211,8 @@ assertions on this behavior for your controllers.
213
211
  def create
214
212
  @widget = Widget.new(widget_params)
215
213
  @widget.errors.add(:base, :invalid)
216
- # `respond_with` will render the `new` template again.
214
+ # `respond_with` will render the `new` template again,
215
+ # and set the status based on the configured `error_status`.
217
216
  respond_with @widget
218
217
  end
219
218
  ```
@@ -238,9 +237,37 @@ class WidgetsController < ApplicationController
238
237
  respond_with widget
239
238
  end
240
239
  end
240
+ ```
241
+
242
+ ## Configuring error and redirect statuses
243
+
244
+ By default, `respond_with` will respond to errors on `HTML` & `JS` requests using the HTTP status code `200 OK`,
245
+ and perform redirects using the HTTP status code `302 Found`, both for backwards compatibility reasons.
241
246
 
247
+ You can configure this behavior by setting `config.responders.error_status` and `config.responders.redirect_status` to the desired status codes.
248
+
249
+ ```ruby
250
+ config.responders.error_status = :unprocessable_entity
251
+ config.responders.redirect_status = :see_other
242
252
  ```
243
253
 
254
+ These can also be set in your custom `ApplicationResponder` if you have generated one: (see install instructions)
255
+
256
+ ```ruby
257
+ class ApplicationResponder < ActionController::Responder
258
+ self.error_status = :unprocessable_entity
259
+ self.redirect_status = :see_other
260
+ end
261
+ ```
262
+
263
+ _Note_: the application responder generated for new apps already configures a different set of defaults: `422 Unprocessable Entity` for errors, and `303 See Other` for redirects. _Responders may change the defaults to match these in a future major release._
264
+
265
+ ### Hotwire/Turbo and fetch APIs
266
+
267
+ Hotwire/Turbo expects successful redirects after form submissions to respond with HTTP status `303 See Other`, and error responses to be 4xx or 5xx statuses, for example `422 Unprocessable Entity` for displaying form validation errors and `500 Internal Server Error` for other server errors. [Turbo documentation: Redirecting After a Form Submission](https://turbo.hotwired.dev/handbook/drive#redirecting-after-a-form-submission).
268
+
269
+ The example configuration showed above matches the statuses that better integrate with Hotwire/Turbo.
270
+
244
271
  ## Examples
245
272
 
246
273
  Want more examples ? Check out these blog posts:
@@ -249,10 +276,15 @@ Want more examples ? Check out these blog posts:
249
276
  * [Three reasons to love ActionController::Responder](http://weblog.rubyonrails.org/2009/8/31/three-reasons-love-responder/)
250
277
  * [My five favorite things about Rails 3](http://www.engineyard.com/blog/2009/my-five-favorite-things-about-rails-3)
251
278
 
279
+ ## Supported Ruby / Rails versions
280
+
281
+ We intend to maintain support for all Ruby / Rails versions that haven't reached end-of-life.
282
+
283
+ For more information about specific versions please check [Ruby](https://www.ruby-lang.org/en/downloads/branches/)
284
+ and [Rails](https://guides.rubyonrails.org/maintenance_policy.html) maintenance policies, and our test matrix.
285
+
252
286
  ## Bugs and Feedback
253
287
 
254
288
  If you discover any bugs or want to drop a line, feel free to create an issue on GitHub.
255
289
 
256
- http://github.com/heartcombo/responders/issues
257
-
258
290
  MIT License. Copyright 2020 Rafael França, Carlos Antônio da Silva. Copyright 2009-2019 Plataformatec.
@@ -3,7 +3,7 @@
3
3
  require "active_support/core_ext/array/extract_options"
4
4
  require "action_controller/metal/mime_responds"
5
5
 
6
- module ActionController #:nodoc:
6
+ module ActionController # :nodoc:
7
7
  module RespondWith
8
8
  extend ActiveSupport::Concern
9
9
 
@@ -95,7 +95,10 @@ module ActionController #:nodoc:
95
95
  # i.e. its +show+ action.
96
96
  # 2. If there are validation errors, the response
97
97
  # renders a default action, which is <tt>:new</tt> for a
98
- # +post+ request or <tt>:edit</tt> for +patch+ or +put+.
98
+ # +post+ request or <tt>:edit</tt> for +patch+ or +put+,
99
+ # and the status is set based on the configured `error_status`.
100
+ # (defaults to `422 Unprocessable Entity` on new apps,
101
+ # `200 OK` for compatibility reasons on old apps.)
99
102
  # Thus an example like this -
100
103
  #
101
104
  # respond_to :html, :xml
@@ -116,8 +119,8 @@ module ActionController #:nodoc:
116
119
  # format.html { redirect_to(@user) }
117
120
  # format.xml { render xml: @user }
118
121
  # else
119
- # format.html { render action: "new" }
120
- # format.xml { render xml: @user }
122
+ # format.html { render action: "new", status: :unprocessable_entity }
123
+ # format.xml { render xml: @user, status: :unprocessable_entity }
121
124
  # end
122
125
  # end
123
126
  # end
@@ -194,7 +197,7 @@ module ActionController #:nodoc:
194
197
  # need to render a template which is outside of controller's path or you
195
198
  # want to override the default http <tt>:status</tt> code, e.g.
196
199
  #
197
- # respond_with(resource, render: { template: 'path/to/template', status: 422 })
200
+ # respond_with(resource, render: { template: 'path/to/template', status: 418 })
198
201
  def respond_with(*resources, &block)
199
202
  if self.class.mimes_for_respond_to.empty?
200
203
  raise "In order to use respond_with, first you need to declare the " \
@@ -239,7 +242,7 @@ module ActionController #:nodoc:
239
242
 
240
243
  # Collect mimes declared in the class method respond_to valid for the
241
244
  # current action.
242
- def collect_mimes_from_class_level #:nodoc:
245
+ def collect_mimes_from_class_level # :nodoc:
243
246
  action = action_name.to_sym
244
247
 
245
248
  self.class.mimes_for_respond_to.keys.select do |mime|
@@ -2,7 +2,7 @@
2
2
 
3
3
  require "active_support/json"
4
4
 
5
- module ActionController #:nodoc:
5
+ module ActionController # :nodoc:
6
6
  # Responsible for exposing a resource to different mime requests,
7
7
  # usually depending on the HTTP verb. The responder is triggered when
8
8
  # <code>respond_with</code> is called. The simplest case to study is a GET request:
@@ -49,7 +49,7 @@ module ActionController #:nodoc:
49
49
  # format.html { redirect_to(@user) }
50
50
  # format.xml { render xml: @user, status: :created, location: @user }
51
51
  # else
52
- # format.html { render action: "new" }
52
+ # format.html { render action: "new", status: :unprocessable_entity }
53
53
  # format.xml { render xml: @user.errors, status: :unprocessable_entity }
54
54
  # end
55
55
  # end
@@ -113,13 +113,16 @@ module ActionController #:nodoc:
113
113
  # if @task.save
114
114
  # flash[:notice] = 'Task was successfully created.'
115
115
  # else
116
- # format.html { render "some_special_template" }
116
+ # format.html { render "some_special_template", status: :unprocessable_entity }
117
117
  # end
118
118
  # end
119
119
  # end
120
120
  #
121
121
  # Using <code>respond_with</code> with a block follows the same syntax as <code>respond_to</code>.
122
122
  class Responder
123
+ class_attribute :error_status, default: :ok, instance_writer: false, instance_predicate: false
124
+ class_attribute :redirect_status, default: :found, instance_writer: false, instance_predicate: false
125
+
123
126
  attr_reader :controller, :request, :format, :resource, :resources, :options
124
127
 
125
128
  DEFAULT_ACTIONS_FOR_VERBS = {
@@ -202,9 +205,9 @@ module ActionController #:nodoc:
202
205
  if get?
203
206
  raise error
204
207
  elsif has_errors? && default_action
205
- render rendering_options
208
+ render error_rendering_options
206
209
  else
207
- redirect_to navigation_location
210
+ redirect_to navigation_location, status: redirect_status
208
211
  end
209
212
  end
210
213
 
@@ -236,6 +239,8 @@ module ActionController #:nodoc:
236
239
  def default_render
237
240
  if @default_response
238
241
  @default_response.call(options)
242
+ elsif !get? && has_errors?
243
+ controller.render({ status: error_status }.merge!(options))
239
244
  else
240
245
  controller.render(options)
241
246
  end
@@ -263,6 +268,8 @@ module ActionController #:nodoc:
263
268
  end
264
269
 
265
270
  def display_errors
271
+ # TODO: use `error_status` once we switch the default to be `unprocessable_entity`,
272
+ # otherwise we'd be changing this behavior here now.
266
273
  controller.render format => resource_errors, :status => :unprocessable_entity
267
274
  end
268
275
 
@@ -300,11 +307,11 @@ module ActionController #:nodoc:
300
307
  @default_response.present?
301
308
  end
302
309
 
303
- def rendering_options
310
+ def error_rendering_options
304
311
  if options[:render]
305
312
  options[:render]
306
313
  else
307
- { action: default_action }
314
+ { action: default_action, status: error_status }
308
315
  end
309
316
  end
310
317
  end
@@ -8,15 +8,19 @@ module Responders
8
8
  desc "Creates an initializer with default responder configuration and copy locale file"
9
9
 
10
10
  def create_responder_file
11
- create_file "lib/application_responder.rb", <<-RUBY
12
- class ApplicationResponder < ActionController::Responder
13
- include Responders::FlashResponder
14
- include Responders::HttpCacheResponder
15
-
16
- # Redirects resources to the collection path (index action) instead
17
- # of the resource path (show action) for POST/PUT/DELETE requests.
18
- # include Responders::CollectionResponder
19
- end
11
+ create_file "lib/application_responder.rb", <<~RUBY
12
+ class ApplicationResponder < ActionController::Responder
13
+ include Responders::FlashResponder
14
+ include Responders::HttpCacheResponder
15
+
16
+ # Redirects resources to the collection path (index action) instead
17
+ # of the resource path (show action) for POST/PUT/DELETE requests.
18
+ # include Responders::CollectionResponder
19
+
20
+ # Configure default status codes for responding to errors and redirects.
21
+ self.error_status = :unprocessable_entity
22
+ self.redirect_status = :see_other
23
+ end
20
24
  RUBY
21
25
  end
22
26
 
@@ -20,6 +20,7 @@ module Responders
20
20
  #
21
21
  def navigation_location
22
22
  return options[:location] if options[:location]
23
+
23
24
  klass = resources.last.class
24
25
 
25
26
  if klass.respond_to?(:model_name)
@@ -37,6 +37,6 @@ module Responders
37
37
  end
38
38
  end
39
39
 
40
- ActiveSupport.on_load(:action_controller) do
40
+ ActiveSupport.on_load(:action_controller_base) do
41
41
  ActionController::Base.extend Responders::ControllerMethod
42
42
  end
@@ -72,7 +72,7 @@ module Responders
72
72
  #
73
73
  # respond_with(@user, :notice => "Hooray! Welcome!", :alert => "Woot! You failed.")
74
74
  #
75
- # * :flash_now - Sets the flash message using flash.now. Accepts true, :on_failure or :on_sucess.
75
+ # * :flash_now - Sets the flash message using flash.now. Accepts true, :on_failure or :on_success.
76
76
  #
77
77
  # == Configure status keys
78
78
  #
@@ -86,15 +86,11 @@ module Responders
86
86
  #
87
87
  module FlashResponder
88
88
  class << self
89
- attr_accessor :flash_keys, :namespace_lookup, :helper
89
+ attr_accessor :flash_keys, :namespace_lookup
90
90
  end
91
91
 
92
92
  self.flash_keys = [ :notice, :alert ]
93
93
  self.namespace_lookup = false
94
- self.helper = Object.new.extend(
95
- ActionView::Helpers::TranslationHelper,
96
- ActionView::Helpers::TagHelper
97
- )
98
94
 
99
95
  def initialize(controller, resources, options = {})
100
96
  super
@@ -128,7 +124,7 @@ module Responders
128
124
  return if controller.flash[status].present?
129
125
 
130
126
  options = mount_i18n_options(status)
131
- message = Responders::FlashResponder.helper.t options[:default].shift, **options
127
+ message = controller.helpers.t options[:default].shift, **options
132
128
  set_flash(status, message)
133
129
  end
134
130
 
@@ -144,11 +140,11 @@ module Responders
144
140
  (default_action && (has_errors? ? @flash_now == :on_failure : @flash_now == :on_success))
145
141
  end
146
142
 
147
- def set_flash_message? #:nodoc:
143
+ def set_flash_message? # :nodoc:
148
144
  !get? && @flash != false
149
145
  end
150
146
 
151
- def mount_i18n_options(status) #:nodoc:
147
+ def mount_i18n_options(status) # :nodoc:
152
148
  options = {
153
149
  default: flash_defaults_by_namespace(status),
154
150
  resource_name: resource_name,
@@ -164,12 +160,7 @@ module Responders
164
160
  end
165
161
 
166
162
  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
163
+ controller.send(:flash_interpolation_options) if controller.respond_to?(:flash_interpolation_options, true)
173
164
  end
174
165
 
175
166
  def resource_name
@@ -180,7 +171,7 @@ module Responders
180
171
  end
181
172
  end
182
173
 
183
- def flash_defaults_by_namespace(status) #:nodoc:
174
+ def flash_defaults_by_namespace(status) # :nodoc:
184
175
  defaults = []
185
176
  slices = controller.controller_path.split("/")
186
177
  lookup = Responders::FlashResponder.namespace_lookup
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Responders
4
- VERSION = "3.0.1"
4
+ VERSION = "3.1.0"
5
5
  end
data/lib/responders.rb CHANGED
@@ -12,7 +12,6 @@ module Responders
12
12
  autoload :FlashResponder, "responders/flash_responder"
13
13
  autoload :HttpCacheResponder, "responders/http_cache_responder"
14
14
  autoload :CollectionResponder, "responders/collection_responder"
15
- autoload :LocationResponder, "responders/location_responder"
16
15
 
17
16
  require "responders/controller_method"
18
17
 
@@ -20,6 +19,8 @@ module Responders
20
19
  config.responders = ActiveSupport::OrderedOptions.new
21
20
  config.responders.flash_keys = [:notice, :alert]
22
21
  config.responders.namespace_lookup = false
22
+ config.responders.error_status = :ok
23
+ config.responders.redirect_status = :found
23
24
 
24
25
  # Add load paths straight to I18n, so engines and application can overwrite it.
25
26
  require "active_support/i18n"
@@ -28,6 +29,8 @@ module Responders
28
29
  initializer "responders.flash_responder" do |app|
29
30
  Responders::FlashResponder.flash_keys = app.config.responders.flash_keys
30
31
  Responders::FlashResponder.namespace_lookup = app.config.responders.namespace_lookup
32
+ ActionController::Responder.error_status = app.config.responders.error_status
33
+ ActionController::Responder.redirect_status = app.config.responders.redirect_status
31
34
  end
32
35
  end
33
36
  end
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: 3.0.1
4
+ version: 3.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - José Valim
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-05-29 00:00:00.000000000 Z
11
+ date: 2023-02-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: railties
@@ -16,28 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '5.0'
19
+ version: '5.2'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '5.0'
26
+ version: '5.2'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: actionpack
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '5.0'
33
+ version: '5.2'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '5.0'
40
+ version: '5.2'
41
41
  description: A set of Rails responders to dry up your application
42
42
  email: heartcombo@googlegroups.com
43
43
  executables: []
@@ -60,13 +60,16 @@ files:
60
60
  - lib/responders/flash_responder.rb
61
61
  - lib/responders/http_cache_responder.rb
62
62
  - lib/responders/locales/en.yml
63
- - lib/responders/location_responder.rb
64
63
  - lib/responders/version.rb
65
64
  homepage: https://github.com/heartcombo/responders
66
65
  licenses:
67
66
  - MIT
68
- metadata: {}
69
- post_install_message:
67
+ metadata:
68
+ homepage_uri: https://github.com/heartcombo/responders
69
+ changelog_uri: https://github.com/heartcombo/responders/blob/master/CHANGELOG.md
70
+ source_code_uri: https://github.com/heartcombo/responders
71
+ bug_tracker_uri: https://github.com/heartcombo/responders/issues
72
+ post_install_message:
70
73
  rdoc_options: []
71
74
  require_paths:
72
75
  - lib
@@ -74,15 +77,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
74
77
  requirements:
75
78
  - - ">="
76
79
  - !ruby/object:Gem::Version
77
- version: 2.4.0
80
+ version: 2.5.0
78
81
  required_rubygems_version: !ruby/object:Gem::Requirement
79
82
  requirements:
80
83
  - - ">="
81
84
  - !ruby/object:Gem::Version
82
85
  version: '0'
83
86
  requirements: []
84
- rubygems_version: 3.1.2
85
- signing_key:
87
+ rubygems_version: 3.4.5
88
+ signing_key:
86
89
  specification_version: 4
87
90
  summary: A set of Rails responders to dry up your application
88
91
  test_files: []
@@ -1,10 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Responders
4
- module LocationResponder
5
- def self.included(_base)
6
- ActiveSupport::Deprecation.warn "Responders::LocationResponder is enabled by default, " \
7
- "no need to include it", caller
8
- end
9
- end
10
- end