respond_for_helper 1.0.0 → 1.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: f7f17979b8269d9fad0e710e0f593e6688477368e32a8d229f4ca8aeda7058e9
4
- data.tar.gz: 7995b1e3ae788d7332f4cf3885a78946ad1980731e89cb7a2658e88608aba35c
3
+ metadata.gz: 605ea6e5b57890e065931756614d979f3f131a6581525622feb96d51c56dc91b
4
+ data.tar.gz: d7bd4702e2a3a0986b19b18361e39c24a8be69472e4c6f594ba51dae3971a3a0
5
5
  SHA512:
6
- metadata.gz: d87eb932d5b4b2e7f9cbe8a5d9630a7633c40827bd6596b907e5094d801f685ed86d43b895be7564702547edb10b4f87ea91e9a4a509ee6b174be0bb45244c12
7
- data.tar.gz: 33a6df7945b5d6acd9cf5da7bb50b3376533eb3746c669f4a4e2f31ee25a8dbfde5fa04cb5b92ee269d840e622e24fd8de817c48897a3431d8fdaa58ba6241dd
6
+ metadata.gz: ea3adad9460730c33cc318cdebe611c7ce76199241e5c83d6d6c885fdc665070aeabafefc7f1cfb5c4d2d8490c096a73d62a69a05423219e56cf35b10403b899
7
+ data.tar.gz: a57499b403d33f4e844f73ce0faf495954922d4d21848ee3bf3dac69e7b62ffb5ef92d652149827b4269f346043e75a96f5e6293adbd23d6cf0b9f88622ae94d
@@ -8,23 +8,37 @@ jobs:
8
8
  strategy:
9
9
  fail-fast: false
10
10
  matrix:
11
- ruby: [2.3, 2.4, 2.5, 2.6, 2.7, 3.0]
12
- gemfile: ['rails50', 'rails51', 'rails52', 'rails60', 'rails61']
11
+ ruby: [2.3, 2.4, 2.5, 2.6, 2.7, '3.0', 3.1]
12
+ gemfile: ['rails50', 'rails51', 'rails52', 'rails60', 'rails61', 'rails70']
13
13
  exclude:
14
14
  - ruby: 2.3
15
15
  gemfile: rails60
16
16
  - ruby: 2.3
17
17
  gemfile: rails61
18
+ - ruby: 2.3
19
+ gemfile: rails70
18
20
  - ruby: 2.4
19
21
  gemfile: rails60
20
22
  - ruby: 2.4
21
23
  gemfile: rails61
24
+ - ruby: 2.4
25
+ gemfile: rails70
26
+ - ruby: 2.5
27
+ gemfile: rails70
28
+ - ruby: 2.6
29
+ gemfile: rails70
22
30
  - ruby: 3.0
23
31
  gemfile: rails50
24
32
  - ruby: 3.0
25
33
  gemfile: rails51
26
34
  - ruby: 3.0
27
35
  gemfile: rails52
36
+ - ruby: 3.1
37
+ gemfile: rails50
38
+ - ruby: 3.1
39
+ gemfile: rails51
40
+ - ruby: 3.1
41
+ gemfile: rails52
28
42
 
29
43
  name: ruby ${{ matrix.ruby }}, ${{ matrix.gemfile }}
30
44
 
data/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 1.1.0
4
+
5
+ * Add `formats` option to `respond_for`.
6
+ * Add `status` and `failure_status` option to `respond_for`.
7
+ * Support `any` and `turbo_stream` format.
8
+ * Make `RespondForHelper.config` more configurable.
9
+ `formats` option is renamed with `formatters` and introduce new `formats` option.
10
+ `default_behaviours` is renamed with `behaviours` and all of its configuration values are changed.
11
+ * The block of `respond_for` now takes format option like `respond_to`.
12
+ If you want to call some process after respond, use `after_success` callback instead.
13
+
14
+ ## 1.0.2
15
+
16
+ * Change redirect status to 303 (see other).
17
+
18
+ ## 1.0.1
19
+
20
+ * Fix render status.
21
+
3
22
  ## 1.0.0
4
23
 
5
24
  * First release.
data/README.md CHANGED
@@ -37,10 +37,21 @@ end
37
37
  ```
38
38
 
39
39
  this action is succeeded when `@item.errors` is empty, otherwise this action is failed.
40
- This action returns html or json corresponding to the request format.
40
+ This action returns html, json or any data corresponding to the request format.
41
41
 
42
42
  `respond_for` allows some options as follows:
43
43
 
44
+ ```ruby
45
+ # Always success without checking error existence.
46
+ respond_for @item, success: true
47
+
48
+ # Enable or disable some formats.
49
+ respond_for @item, html: true, json: true, any: false
50
+
51
+ ```
52
+
53
+ `respond_for` also supports short options for html format:
54
+
44
55
  ```ruby
45
56
  # Specify redirect location when succeeded.
46
57
  # The value should be one of string, symbol (action name) or proc.
@@ -55,13 +66,29 @@ respond_for @item, notice: 'Create was succceeded'
55
66
 
56
67
  # Specify alert message when failed.
57
68
  respond_for @item, alert: 'Create was failed'
69
+ ```
58
70
 
59
- # Always success without checking error existence.
60
- respond_for @item, success: true
71
+ `respond_for` also supports block like `respond_to`:
61
72
 
62
- # Block is called when succeeded.
63
- respond_for @item do
64
- puts "succeeded"
73
+ ```ruby
74
+ # Use full-customized behaviour.
75
+ respond_for @item do |format, respond|
76
+ if respond.success?
77
+ format.html { redirect_to action: :index }
78
+ else
79
+ format.html { redirect_to action: :show }
80
+ end
81
+ end
82
+ ```
83
+
84
+ You can use callbacks like `after_success` or `after_failure` in the block.
85
+ Note that the callbacks are called after running respond behaviours like `render` or `redirect`:
86
+
87
+ ```ruby
88
+ # Set callbacks running after respond.
89
+ respond_for @item do |format, respond|
90
+ respond.after_success { puts "succeeded" }
91
+ respond.after_failure { puts "failed" }
65
92
  end
66
93
  ```
67
94
 
@@ -100,16 +127,16 @@ you can use `respond_for_message` as follows:
100
127
  ```ruby
101
128
  class ItemsController < ActionController::Base
102
129
  def create
103
- respond_for_mesasge :notice
130
+ respond_for_message :notice
104
131
  #=> Successfully created (2021-01-01 10:00)
105
132
 
106
- respond_for_mesasge :notice, success_num: 10
133
+ respond_for_message :notice, success_num: 10
107
134
  #=> Successfully created (10 succeeded) (2021-01-01 10:00)
108
135
 
109
- respond_for_mesasge :notice, action_name: :update
136
+ respond_for_message :notice, action_name: :update
110
137
  #=> Successfully updated (2021-01-01 10:00)
111
138
 
112
- respond_for_mesasge :alert
139
+ respond_for_message :alert
113
140
  #=> Failed to create (2021-01-01 10:00)
114
141
  end
115
142
  end
@@ -140,20 +167,23 @@ For example:
140
167
 
141
168
  ```ruby
142
169
  RespondForHelper.configure do |config|
143
- config.default_behaviours = {
144
- template: {},
145
- location: {},
146
- failure_template: { create: :new, update: :edit, destroy: :show, _default: :show },
147
- failure_location: { _default: :show }
170
+ config.behaviours = {
171
+ html: {
172
+ index: { render: :index },
173
+ show: { render: :show },
174
+ create: {
175
+ success: { redirect: :index, status: :see_other, flash: :notice },
176
+ failure: { render: :new, status: :unprocessable_entity, flash: :alert }
177
+ }
178
+ }
148
179
  }
149
180
  end
150
181
  ```
151
182
 
152
- `template` and `location` is used when current action is succeeded,
153
- while `failure_template` and `failure_location` is used when current action is failed.
154
- All of them contains action name mapping:
155
- the key of mapping is a current action and the value of mapping is a next action after succeeded or failed.
156
- `_default` is a common action which is applied to all of actions which have not specific mapping.
183
+ `html` is a request format.
184
+ `index`, `show`, `create` is a action name of your controller.
185
+ `success` is used when current action is succeeded, while `failure` is used when current action is failed.
186
+ All of them contains default behaviours which are defined as `render`, `redirect` or `head`.
157
187
 
158
188
  #### Controller-specific behaviours
159
189
 
@@ -161,41 +191,45 @@ You can also customize controller-specific behaviours:
161
191
 
162
192
  ```ruby
163
193
  class ItemsController < ActionController::Base
164
- self.respond_for_behaviours = {
165
- location: { _default: :show }
194
+ self.respond_for_config = {
195
+ html: {
196
+ create: {
197
+ success: { redirect: :show }
198
+ }
199
+ }
166
200
  }
167
201
  end
168
202
  ```
169
203
 
170
- The way of setting is same as `config.default_behaviours`.
204
+ The way of setting is same as `config.behaviours`.
171
205
 
172
206
  #### Format processors
173
207
 
174
- you can also set your own format processors as you like:
208
+ You can also set your own format processors as you like:
175
209
 
176
210
  ```ruby
177
211
  RespondForHelper.configure do |config|
178
- config.formats = {
212
+ config.formats = [:html, :json, :any]
213
+ config.formatters = {
179
214
  html: RespondForHelper::Formats::Html,
180
- json: RespondForHelper::Formats::Json
215
+ json: RespondForHelper::Formats::Json,
216
+ any: RespondForHelper::Formats::Any
181
217
  }
182
- config.flash = RespondForHelper::Flashes::Timestamp
183
218
  end
184
219
  ```
185
220
 
186
221
  Format processors should be extended by `RespondForHelper::Formats::Base`.
187
222
 
188
- you can also set your own flash message generators:
223
+ You can also set your own flash message generators:
189
224
 
190
225
  ```ruby
191
226
  RespondForHelper.configure do |config|
192
- config.flash = RespondForHelper::Flashes::Timestamp
227
+ config.flasher = RespondForHelper::Flashes::Timestamp
193
228
  end
194
229
  ```
195
230
 
196
231
  Flash message generators should be extended by `RespondForHelper::Flashes::Base`.
197
232
 
198
-
199
233
  ## Contributing
200
234
 
201
235
  Bug reports and pull requests are welcome at https://github.com/kanety/respond_for_helper.
@@ -1,5 +1,6 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
3
  gem "rails", "~> 6.0.0"
4
+ gem "psych", "~> 3.3.0"
4
5
 
5
6
  gemspec path: "../"
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem "rails", "~> 7.0.1"
4
+
5
+ gemspec path: "../"
@@ -0,0 +1,123 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RespondForHelper
4
+ class Behaviour
5
+ TYPES = [:render, :redirect, :head]
6
+
7
+ attr_accessor :type, :target, :flash, :options
8
+
9
+ def initialize(attrs)
10
+ @type = attrs.delete(:type)
11
+ @target = attrs.delete(:target)
12
+ @flash = attrs.delete(:flash)
13
+ @options = attrs
14
+ end
15
+
16
+ def render?
17
+ @type == :render
18
+ end
19
+
20
+ def redirect?
21
+ @type == :redirect
22
+ end
23
+
24
+ def head?
25
+ @type == :head
26
+ end
27
+
28
+ def flash?
29
+ @flash
30
+ end
31
+ end
32
+
33
+ class Behaviours
34
+ def initialize(controller, format, result, options)
35
+ @controller = controller
36
+ @format = format
37
+ @result = result
38
+ @options = options
39
+
40
+ @controller_behaviours = @controller.respond_for_config.fetch(:behaviours, {})
41
+ @default_behaviours = Config.behaviours
42
+ end
43
+
44
+ def call
45
+ behaviour = Behaviour.new(resolve_attributes)
46
+
47
+ if @format == :html
48
+ merge_html_options(behaviour)
49
+ end
50
+
51
+ behaviour
52
+ end
53
+
54
+ private
55
+
56
+ def resolve_attributes
57
+ keys1 = [@format, @controller.action_name.to_sym, @result]
58
+ keys2 = [@format, @controller.action_name.to_sym]
59
+ keys3 = [@format, :_default, @result]
60
+ keys4 = [@format, :_default]
61
+
62
+ attrs = {}
63
+ attrs.merge!(resolve_attributes_for(@default_behaviours, [keys1, keys2, keys3, keys4]))
64
+ attrs.merge!(resolve_attributes_for(@controller_behaviours, [keys1, keys2, keys3, keys4]))
65
+ attrs.merge!(resolve_attributes_for(@options, [[@format, @result], [@format]]))
66
+ attrs.empty? ? { type: :redirect, target: :index } : attrs
67
+ end
68
+
69
+ def resolve_attributes_for(behaviours, keys_list)
70
+ keys_list.each do |keys|
71
+ if (attrs = behaviours.dig(*keys))
72
+ attrs = attrs.deep_dup
73
+ Behaviour::TYPES.each do |type|
74
+ if attrs[type]
75
+ attrs[:type] = type
76
+ attrs[:target] = attrs.delete(type)
77
+ end
78
+ end
79
+ return attrs
80
+ end
81
+ end
82
+ {}
83
+ end
84
+
85
+ def merge_html_options(behaviour)
86
+ if @result == :success
87
+ if @options[:template]
88
+ change_to_render(behaviour) if behaviour.type != :render
89
+ behaviour.target = @options[:template]
90
+ end
91
+ if @options[:location]
92
+ change_to_redirect(behaviour) if behaviour.type != :redirect
93
+ behaviour.target = @options[:location]
94
+ end
95
+ if @options[:status]
96
+ behaviour.options[:status] = @options[:status]
97
+ end
98
+ else
99
+ if @options[:failure_template]
100
+ change_to_render(behaviour) if behaviour.type != :render
101
+ behaviour.target = @options[:failure_template]
102
+ end
103
+ if @options[:failure_location]
104
+ change_to_redirect(behaviour) if behaviour.type != :redirect
105
+ behaviour.target = @options[:failure_location]
106
+ end
107
+ if @options[:failure_status]
108
+ behaviour.options[:status] = @options[:failure_status]
109
+ end
110
+ end
111
+ end
112
+
113
+ def change_to_render(behaviour)
114
+ behaviour.type = :render
115
+ behaviour.options[:status] = @result == :success ? :ok : :unprocessable_entity
116
+ end
117
+
118
+ def change_to_redirect(behaviour)
119
+ behaviour.type = :redirect
120
+ behaviour.options[:status] = :see_other
121
+ end
122
+ end
123
+ end
@@ -5,18 +5,66 @@ module RespondForHelper
5
5
  class_attribute :data
6
6
 
7
7
  self.data = {
8
- flash: RespondForHelper::Flashes::Timestamp,
9
- formats: {
8
+ formats: [:html, :json],
9
+ formatters: {
10
+ turbo_stream: RespondForHelper::Formats::TurboStream,
10
11
  html: RespondForHelper::Formats::Html,
11
- json: RespondForHelper::Formats::Json
12
+ json: RespondForHelper::Formats::Json,
13
+ any: RespondForHelper::Formats::Any
12
14
  },
13
- default_behaviours: {
14
- template: {},
15
- location: {},
16
- failure_template: { create: :new, update: :edit, destroy: :show, _default: :show },
17
- failure_location: { _default: :show }
18
- },
19
- member_actions: [:show, :edit, :update, :destroy]
15
+ flasher: RespondForHelper::Flashes::Timestamp,
16
+ behaviours: {
17
+ turbo_stream: {
18
+ _default: {
19
+ success: { render: -> { action_name.to_sym }, status: :ok },
20
+ failure: { render: -> { action_name.to_sym }, status: :unprocessable_entity }
21
+ }
22
+ },
23
+ html: {
24
+ index: { render: :index },
25
+ show: { render: :show },
26
+ create: {
27
+ success: { redirect: :index, status: :see_other, flash: :notice },
28
+ failure: { render: :new, status: :unprocessable_entity, flash: :alert }
29
+ },
30
+ update: {
31
+ success: { redirect: :index, status: :see_other, flash: :notice },
32
+ failure: { render: :edit, status: :unprocessable_entity, flash: :alert }
33
+ },
34
+ destroy: {
35
+ success: { redirect: :index, status: :see_other, flash: :notice },
36
+ failure: { render: :show, status: :unprocessable_entity, flash: :alert }
37
+ },
38
+ _default: {
39
+ success: { redirect: :index, status: :see_other, flash: :notice },
40
+ failure: { render: :show, status: :unprocessable_entity, flash: :alert }
41
+ }
42
+ },
43
+ json: {
44
+ index: { render: :item },
45
+ show: { render: :item },
46
+ create: {
47
+ success: { render: :item, status: :created },
48
+ failure: { render: :item_errors, status: :unprocessable_entity }
49
+ },
50
+ update: {
51
+ success: { render: :item, status: :ok },
52
+ failure: { render: :item_errors, status: :unprocessable_entity }
53
+ },
54
+ destroy: {
55
+ success: { head: :no_content },
56
+ failure: { head: :unprocessable_entity }
57
+ },
58
+ _default: {
59
+ success: { render: :item, status: :ok },
60
+ failure: { render: :item_errors, status: :unprocessable_entity }
61
+ }
62
+ },
63
+ any: {
64
+ index: { render: :index },
65
+ show: { render: :show }
66
+ }
67
+ }
20
68
  }
21
69
 
22
70
  data.keys.each do |key|
@@ -5,19 +5,26 @@ module RespondForHelper
5
5
  extend ActiveSupport::Concern
6
6
 
7
7
  def respond_for(item, options = {})
8
- klass = Config.formats[request.format.to_sym] || Config.formats[:html]
9
- formatter = klass.new(self, item, options)
10
- formatter.call
11
- yield if block_given? && formatter.succeeded?
8
+ respond = Respond.new(self, item, options)
9
+ respond_to do |format|
10
+ yield(format, respond) if block_given?
11
+ respond.formatters.each do |formatter|
12
+ format.send(formatter.format) { formatter.call }
13
+ end
14
+ respond.run_before_callbacks
15
+ end
16
+ respond.run_after_callbacks
12
17
  end
13
18
 
14
19
  def respond_for_message(type, options = {})
20
+ klass = Lookups::Flash.new(self, options).call
15
21
  options = options.reverse_merge(controller_path: controller_path, action_name: action_name)
16
- Config.flash.new(type, options).call
22
+ klass.new(type, options).call
17
23
  end
18
24
 
19
25
  included do
20
- class_attribute :respond_for_behaviours
26
+ class_attribute :respond_for_config
27
+ self.respond_for_config = {}
21
28
  end
22
29
  end
23
30
  end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RespondForHelper
4
+ module Formats
5
+ class Any < Html
6
+ self.format = :any
7
+ end
8
+ end
9
+ end
@@ -3,37 +3,58 @@
3
3
  module RespondForHelper
4
4
  module Formats
5
5
  class Base
6
- attr_reader :controller
7
- delegate :request, :respond_to, :render, :head, :redirect_to, :flash, :url_for, :action_name, to: :controller
6
+ class_attribute :format
7
+
8
+ attr_reader :controller, :item, :format, :result, :behaviour
9
+ delegate :request, :render, :head, :redirect_to, :flash, :url_for, :action_name, to: :controller
8
10
 
9
11
  def initialize(controller, item, options)
10
12
  @controller = controller
11
13
  @item = item
12
14
  @options = options
15
+
16
+ @format = self.class.format.to_sym
17
+ @result = @options[:success] ? :success : :failure
18
+ @behaviour = Behaviours.new(@controller, @format, @result, @options).call
13
19
  end
14
20
 
15
21
  def call
16
- respond do
17
- if respond_to?("_#{action_name}", true)
18
- send("_#{action_name}")
19
- else
20
- default_action
21
- end
22
+ if respond_to?("_#{action_name}", true)
23
+ send("_#{action_name}")
24
+ else
25
+ perform
22
26
  end
23
27
  end
24
28
 
29
+ private
30
+
31
+ def perform
32
+ end
33
+
25
34
  def succeeded?
26
- if @options.key?(:success)
27
- @options[:success]
28
- else
29
- Array(@item).all? { |item| item.errors.blank? }
30
- end
35
+ @result == :success
31
36
  end
32
37
 
33
- def respond
38
+ def resolve_target(target)
39
+ if target.respond_to?(:call)
40
+ @controller.instance_exec(&target)
41
+ elsif target.is_a?(Symbol)
42
+ if respond_to?(target)
43
+ send(target)
44
+ elsif @behaviour.redirect?
45
+ resolve_url(target)
46
+ else
47
+ target
48
+ end
49
+ else
50
+ target
51
+ end
34
52
  end
35
53
 
36
- def default_action
54
+ def resolve_url(target)
55
+ url_for(action: target)
56
+ rescue ActionController::UrlGenerationError
57
+ url_for(action: target, id: @item)
37
58
  end
38
59
  end
39
60
  end
@@ -3,84 +3,40 @@
3
3
  module RespondForHelper
4
4
  module Formats
5
5
  class Html < Base
6
- def respond
7
- respond_to do |format|
8
- format.html { yield }
9
- end
10
- end
11
-
12
- def _index
13
- render @options[:template] || :index
14
- end
6
+ self.format = :html
15
7
 
16
- def _show
17
- render @options[:template] || :show
18
- end
8
+ private
19
9
 
20
- def default_action
21
- if succeeded?
22
- render_or_redirect(:template, :location, :notice)
23
- else
24
- render_or_redirect(:failure_template, :failure_location, :alert)
10
+ def perform
11
+ if @behaviour.render?
12
+ perform_render
13
+ elsif @behaviour.redirect?
14
+ perform_redirect
25
15
  end
26
- end
27
16
 
28
- def render_or_redirect(template_key, location_key, type)
29
- behaviour = resolve_behaviour(template_key, location_key)
30
- if behaviour[0] == :template
31
- message = resolve_flash(type)
32
- flash.now[type] = message if message
33
- render resolve_template(behaviour[1]), status: :unprocessable_entity
34
- else
35
- message = resolve_flash(type)
36
- flash[type] = message if message
37
- redirect_to resolve_location(behaviour[1])
17
+ if @behaviour.flash? && !request.xhr?
18
+ perform_flash
38
19
  end
39
20
  end
40
21
 
41
- def resolve_flash(type)
42
- return if request.xhr?
43
- @controller.respond_for_message(type, @options)
22
+ def perform_render
23
+ render resolve_target(@behaviour.target), @behaviour.options
44
24
  end
45
25
 
46
- def resolve_behaviour(template_key, location_key)
47
- [ [:template, @options[template_key]],
48
- [:location, @options[location_key]],
49
- [:template, behaviour_config(template_key)],
50
- [:location, behaviour_config(location_key)]
51
- ].each do |behaviour|
52
- return behaviour if behaviour[1].present?
53
- end
54
- [:location, url_for(action: :index)]
26
+ def perform_redirect
27
+ redirect_to resolve_target(@behaviour.target), @behaviour.options
55
28
  end
56
29
 
57
- def behaviour_config(key)
58
- [@controller.class.respond_for_behaviours, Config.default_behaviours].each do |behaviours|
59
- behaviour = behaviours&.dig(key, action_name.to_sym) || behaviours&.dig(key, :_default)
60
- return behaviour if behaviour
61
- end
62
- return nil
63
- end
64
-
65
- def resolve_template(template)
66
- if template.respond_to?(:call)
67
- @controller.instance_exec(&template)
68
- else
69
- template
70
- end
30
+ def perform_flash
31
+ key = @behaviour.flash
32
+ flash_content[key] = @controller.respond_for_message(key, @options)
71
33
  end
72
34
 
73
- def resolve_location(location)
74
- if location.respond_to?(:call)
75
- @controller.instance_exec(&location)
76
- elsif location.is_a?(Symbol)
77
- if location.in?(Config.member_actions)
78
- url_for(action: location, id: @item)
79
- else
80
- url_for(action: location)
81
- end
82
- else
83
- location
35
+ def flash_content
36
+ if @behaviour.render?
37
+ flash.now
38
+ elsif @behaviour.redirect?
39
+ flash
84
40
  end
85
41
  end
86
42
  end
@@ -3,50 +3,28 @@
3
3
  module RespondForHelper
4
4
  module Formats
5
5
  class Json < Base
6
- def respond
7
- respond_to do |format|
8
- format.json { yield }
9
- end
10
- end
11
-
12
- def _index
13
- render json: @item
14
- end
6
+ self.format = :json
15
7
 
16
- def _show
17
- render json: @item
8
+ def item_errors
9
+ @item.errors
18
10
  end
19
11
 
20
- def _create
21
- if succeeded?
22
- render json: @item, status: :created
23
- else
24
- render json: @item.errors, status: :unprocessable_entity
25
- end
26
- end
12
+ private
27
13
 
28
- def _update
29
- if succeeded?
30
- render json: @item, status: :ok
31
- else
32
- render json: @item.errors, status: :unprocessable_entity
14
+ def perform
15
+ if @behaviour.render?
16
+ perform_render
17
+ elsif @behaviour.head?
18
+ perform_head
33
19
  end
34
20
  end
35
21
 
36
- def _destroy
37
- if succeeded?
38
- head :no_content
39
- else
40
- head :unprocessable_entity
41
- end
22
+ def perform_render
23
+ render @behaviour.options.merge(json: resolve_target(@behaviour.target))
42
24
  end
43
25
 
44
- def default_action
45
- if succeeded?
46
- render json: @item, status: :ok
47
- else
48
- render json: @item.errors, status: :unprocessable_entity
49
- end
26
+ def perform_head
27
+ head resolve_target(@behaviour.target), @behaviour.options
50
28
  end
51
29
  end
52
30
  end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RespondForHelper
4
+ module Formats
5
+ class TurboStream < Html
6
+ self.format = :turbo_stream
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RespondForHelper
4
+ module Lookups
5
+ class Flash
6
+ def initialize(controller, options)
7
+ @controller = controller
8
+ @options = options
9
+
10
+ @controller_config = @controller.class.respond_for_config
11
+ end
12
+
13
+ def call
14
+ if @controller_config[:flasher]
15
+ @controller_config[:flasher]
16
+ else
17
+ Config.flasher
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RespondForHelper
4
+ module Lookups
5
+ class Format
6
+ def initialize(controller, options)
7
+ @controller = controller
8
+ @options = options
9
+
10
+ @controller_config = @controller.class.respond_for_config
11
+ end
12
+
13
+ def call
14
+ formats = adjust_formats(resolve_formats.deep_dup)
15
+ formatters = resolve_formatters
16
+ formatters.select { |format, _| formats.include?(format) }.to_h
17
+ end
18
+
19
+ private
20
+
21
+ def resolve_formats
22
+ if @options[:formats]
23
+ Array(@options[:formats])
24
+ elsif @controller_config[:formats]
25
+ Array(@controller_config[:formats])
26
+ else
27
+ Config.formats
28
+ end
29
+ end
30
+
31
+ def adjust_formats(formats)
32
+ Config.formatters.keys.each do |format|
33
+ if @options[format] == true
34
+ @options.delete(format)
35
+ formats.unshift(format)
36
+ elsif @options[format] == false
37
+ @options.delete(format)
38
+ formats.delete(format)
39
+ end
40
+ end
41
+ formats
42
+ end
43
+
44
+ def resolve_formatters
45
+ if @controller_config[:formatters]
46
+ Array(@controller_config[:formatters])
47
+ else
48
+ Config.formatters
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RespondForHelper
4
+ class Respond
5
+ def initialize(controller, item, options)
6
+ @controller = controller
7
+ @item = item
8
+ @options = options
9
+
10
+ unless @options.key?(:success)
11
+ @options[:success] = Array(item).all? { |item| item.errors.blank? }
12
+ end
13
+
14
+ @callbacks = {}
15
+ end
16
+
17
+ def success?
18
+ @options[:success]
19
+ end
20
+
21
+ def before_success(&block)
22
+ @callbacks[:before_success] ||= []
23
+ @callbacks[:before_success] << block
24
+ end
25
+
26
+ def before_failure(&block)
27
+ @callbacks[:before_failure] ||= []
28
+ @callbacks[:before_failure] << block
29
+ end
30
+
31
+ def after_success(&block)
32
+ @callbacks[:after_success] ||= []
33
+ @callbacks[:after_success] << block
34
+ end
35
+
36
+ def after_failure(&block)
37
+ @callbacks[:after_failure] ||= []
38
+ @callbacks[:after_failure] << block
39
+ end
40
+
41
+ def run_before_callbacks
42
+ if success?
43
+ run_callbacks_for(:before_success)
44
+ else
45
+ run_callbacks_for(:before_failure)
46
+ end
47
+ end
48
+
49
+ def run_after_callbacks
50
+ if success?
51
+ run_callbacks_for(:after_success)
52
+ else
53
+ run_callbacks_for(:after_failure)
54
+ end
55
+ end
56
+
57
+ def run_callbacks_for(name)
58
+ if @callbacks[name]
59
+ @callbacks[name].each do |callback|
60
+ callback.call
61
+ end
62
+ end
63
+ end
64
+
65
+ def formatters
66
+ Lookups::Format.new(@controller, @options).call.map do |_, klass|
67
+ klass.new(@controller, @item, @options)
68
+ end
69
+ end
70
+ end
71
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RespondForHelper
4
- VERSION = '1.0.0'
4
+ VERSION = '1.1.0'
5
5
  end
@@ -4,10 +4,16 @@ require 'active_support/all'
4
4
 
5
5
  require 'respond_for_helper/formats/base'
6
6
  require 'respond_for_helper/formats/html'
7
+ require 'respond_for_helper/formats/turbo_stream'
7
8
  require 'respond_for_helper/formats/json'
9
+ require 'respond_for_helper/formats/any'
8
10
  require 'respond_for_helper/flashes/base'
9
11
  require 'respond_for_helper/flashes/timestamp'
10
12
  require 'respond_for_helper/config'
13
+ require 'respond_for_helper/lookups/format'
14
+ require 'respond_for_helper/lookups/flash'
15
+ require 'respond_for_helper/behaviour'
16
+ require 'respond_for_helper/respond'
11
17
  require 'respond_for_helper/controller'
12
18
  require 'respond_for_helper/helper'
13
19
  require 'respond_for_helper/railtie' if defined?(Rails)
@@ -24,4 +24,5 @@ Gem::Specification.new do |spec|
24
24
  spec.add_development_dependency "rake"
25
25
  spec.add_development_dependency "rspec-rails"
26
26
  spec.add_development_dependency "simplecov"
27
+ spec.add_development_dependency "webrick"
27
28
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: respond_for_helper
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yoshikazu Kaneta
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-09-21 00:00:00.000000000 Z
11
+ date: 2022-07-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -94,6 +94,20 @@ dependencies:
94
94
  - - ">="
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: webrick
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
97
111
  description: A rails helper for responding request format
98
112
  email:
99
113
  - kaneta@sitebridge.co.jp
@@ -116,18 +130,25 @@ files:
116
130
  - gemfiles/rails52.gemfile
117
131
  - gemfiles/rails60.gemfile
118
132
  - gemfiles/rails61.gemfile
133
+ - gemfiles/rails70.gemfile
119
134
  - lib/respond_for_helper.rb
135
+ - lib/respond_for_helper/behaviour.rb
120
136
  - lib/respond_for_helper/config.rb
121
137
  - lib/respond_for_helper/controller.rb
122
138
  - lib/respond_for_helper/flashes/base.rb
123
139
  - lib/respond_for_helper/flashes/timestamp.rb
140
+ - lib/respond_for_helper/formats/any.rb
124
141
  - lib/respond_for_helper/formats/base.rb
125
142
  - lib/respond_for_helper/formats/html.rb
126
143
  - lib/respond_for_helper/formats/json.rb
144
+ - lib/respond_for_helper/formats/turbo_stream.rb
127
145
  - lib/respond_for_helper/helper.rb
128
146
  - lib/respond_for_helper/locales/en.yml
129
147
  - lib/respond_for_helper/locales/ja.yml
148
+ - lib/respond_for_helper/lookups/flash.rb
149
+ - lib/respond_for_helper/lookups/format.rb
130
150
  - lib/respond_for_helper/railtie.rb
151
+ - lib/respond_for_helper/respond.rb
131
152
  - lib/respond_for_helper/version.rb
132
153
  - respond_for_helper.gemspec
133
154
  homepage: https://github.com/kanety/respond_for_helper
@@ -148,7 +169,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
148
169
  - !ruby/object:Gem::Version
149
170
  version: '0'
150
171
  requirements: []
151
- rubygems_version: 3.1.2
172
+ rubygems_version: 3.3.3
152
173
  signing_key:
153
174
  specification_version: 4
154
175
  summary: A rails helper for responding request format