responders 3.0.1 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 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