respond_for_helper 1.0.0 → 1.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: 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