mime_actor 0.5.1 → 0.5.3

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: 21576d34311aa9a06ac9542d118390900d8b9e3d9860fb6ed7d1a4a9b672bf96
4
- data.tar.gz: a2ca714375f7892e1506bf55b5fcdbbaa3b1ea7884b9f2ad7a1b4284d3fed08a
3
+ metadata.gz: 709cab49cc347653da124ec9147c7527b96f71df08059b6eab45a5d9b5b06888
4
+ data.tar.gz: ac9a75000c8711550971fa0d6e4f0ba3bc2b9e706ebd1654702df1b56d3e0f5d
5
5
  SHA512:
6
- metadata.gz: c24629937c5b2d7626588b1ef8ffa1d334450bda5dafe90693d0c65bfc5200d8122e0fdbd315206538c85cb6d8aae29eedf7f07289b3971a13f0a6903d757c0b
7
- data.tar.gz: 07d9061ef2e41f55b0e5e9718f9a719a4da2309232be87bf59f638e2a0f9502cfbcdaa6f054f9e2764b9c9b5a9bb1cd5a3a8544a6844902d5dd1f72d07b8ea1f
6
+ metadata.gz: 40fe1d6ba3560b836c12ec423d8285497f2576f231a385ecf910942cedd8be7c36ea1d20077283f2aa336c0aa1beab92a6472b998a63fde4a3b9de1e71f5a9c3
7
+ data.tar.gz: 5dc2dcc8697d65e386bf47f898b4ed85b8fe7d364ddfce84be873b966653c713e788c994a57e879e439ae1f6401e69092905dd88319a52c94f8c1be817daa1ca
data/COMPARE.md ADDED
@@ -0,0 +1,124 @@
1
+ ## Comparison in Rails
2
+
3
+ ### MIME Rendering
4
+
5
+ #### before
6
+ ```rb
7
+ class EventsController < ActionController::Base
8
+ def index
9
+ @events = Event.all
10
+ respond_to do |format|
11
+ format.html do
12
+ @event_categories = EventCategory.all
13
+
14
+ # render html using @events and @event_categories
15
+ render :index
16
+ end
17
+ format.json { render json: @events } # render json using #as_json
18
+ end
19
+ end
20
+ end
21
+ ```
22
+ #### after
23
+ ```rb
24
+ class EventsController < ActionController::Base
25
+ include MimeActor::Action
26
+
27
+ before_action only: :index { @events = Event.all }
28
+
29
+ # dynamically defines the action method according to on: argument
30
+ compose_scene :html, :json, on: :index
31
+
32
+ def index_html
33
+ @event_categories = EventCategory.all
34
+
35
+ # render html using @events and @event_categories
36
+ render :index
37
+ end
38
+
39
+ def index_json
40
+ # render json using #as_json
41
+ render json: @events
42
+ end
43
+ end
44
+ ```
45
+
46
+ ### MIME Rescuing
47
+
48
+ #### before
49
+ ```rb
50
+ class EventsController < ActionController::Base
51
+ # AbstractController::Callbacks here to load model with params
52
+ before_action only: [:show, :update] { @event = Event.find(params.require(:event_id)) }
53
+
54
+ rescue_from ActiveRecord::RecordNotFound do |ex|
55
+ case action_name.to_s
56
+ when "show"
57
+ respond_to do |format|
58
+ format.html { redirect_to events_path } # redirect to index
59
+ format.json { render status: :bad_request, json: { error: ex.message } }
60
+ end
61
+ when "update"
62
+ respond_to do |format|
63
+ format.html { render :edit }
64
+ format.json { render status: :bad_request, json: { error: ex.message } }
65
+ end
66
+ else
67
+ raise ex # re-raise since we are not handling it
68
+ end
69
+ end
70
+
71
+ def show
72
+ respond_to do |format|
73
+ format.html { render :show } # render html using @event
74
+ format.json { render json: @event } # render json using #as_json
75
+ end
76
+ end
77
+
78
+ def update
79
+ # ...
80
+ respond_to do |format|
81
+ format.html { redirect_to event_path(@event.id) } # redirect to show upon sucessful update
82
+ format.json { render json: @event } # render json using #as_json
83
+ end
84
+ end
85
+ end
86
+ ```
87
+ #### after
88
+ ```rb
89
+ class EventsController < ActionController::Base
90
+ include MimeActor::Action
91
+
92
+ # AbstractController::Callbacks here to load model with params
93
+ before_action only: [:show, :update] { @event = Event.find(params.require(:event_id)) }
94
+
95
+ compose_scene :html, :json, on: [:show, :update]
96
+
97
+ rescue_actor_from ActiveRecord::RecordNotFound, format: :json do |ex|
98
+ render status: :bad_request, json: { error: ex.message }
99
+ end
100
+
101
+ rescue_actor_from ActiveRecord::RecordNotFound, format: :html, action: :show do |ex|
102
+ redirect_to events_path
103
+ end
104
+
105
+ def show_html
106
+ render :show # render html using @event
107
+ end
108
+
109
+ def update_html
110
+ redirect_to event_path(@event.id) # redirect to show upon sucessful update
111
+ rescue ActiveRecord::RecordNotFound
112
+ render :edit
113
+ end
114
+
115
+ def show_json
116
+ render json: @event # render json using #as_json
117
+ end
118
+
119
+ def update_json
120
+ # ...
121
+ render json: @event # render json using #as_json
122
+ end
123
+ end
124
+ ```
data/README.md CHANGED
@@ -1,10 +1,11 @@
1
1
  # mime_actor
2
2
 
3
- [![Gem Version](https://badge.fury.io/rb/mime_actor.png)](https://badge.fury.io/rb/mime_actor)
4
- [![codecov](https://codecov.io/gh/ryancyq/mime_actor/graph/badge.svg?token=4C091RHXC3)](https://codecov.io/gh/ryancyq/mime_actor)
5
- [![Build](https://github.com/ryancyq/mime_actor/actions/workflows/build.yml/badge.svg)](https://github.com/ryancyq/mime_actor/actions/workflows/build.yml)
3
+ [![Version][rubygems_badge]][rubygems]
4
+ [![CI][ci_badge]][ci_workflows]
5
+ [![Coverage][coverage_badge]][coverage]
6
+ [![Maintainability][maintainability_badge]][maintainability]
6
7
 
7
- Render + Rescue handlers for different MIME types in Rails
8
+ Action Render + Rescue handlers for different MIME types in Rails
8
9
 
9
10
  ## Usage
10
11
 
@@ -56,13 +57,19 @@ class EventsController < ActionController::Base
56
57
  end
57
58
  ```
58
59
 
60
+ Seems useful? See the [Comparison][doc_comparison] on how it can improve your existing code
61
+
59
62
  ## Features
60
63
 
61
- - Action customisation for ActionController per MIME type
64
+ - Action customisation for [ActionController][doc_action_controller] per MIME type
62
65
  - Customisation are deduplicated automatically when configured multiple times
63
66
  - Flexible rescue handler definition for the combination of Action/MIME type or both
64
- - Built on top of `ActionController::Metal::MimeResponds`
65
- - Fully compatible with other `ActionController` functionalities
67
+ - Built on top of [ActionController::Metal::MimeResponds][doc_action_controller_mime_responds]
68
+ - Fully compatible with other [ActionController][doc_action_controller] functionalities
69
+
70
+ ## Documentation
71
+
72
+ You can find the documentation on [RubyDoc][doc_mime_actor].
66
73
 
67
74
  ## Requirements
68
75
 
@@ -93,3 +100,17 @@ Please see [LICENSE](https://github.com/ryancyq/mime_actor/blob/main/LICENSE) fo
93
100
  ## Contributing
94
101
 
95
102
  Bug reports and pull requests are welcome on GitHub at https://github.com/ryancyq/mime_actor.
103
+
104
+ [rubygems_badge]: https://img.shields.io/gem/v/mime_actor.svg
105
+ [rubygems]: https://rubygems.org/gems/mime_actor
106
+ [ci_badge]: https://github.com/ryancyq/mime_actor/actions/workflows/build.yml/badge.svg
107
+ [ci_workflows]: https://github.com/ryancyq/mime_actor/actions/workflows/
108
+ [coverage_badge]: https://codecov.io/gh/ryancyq/mime_actor/graph/badge.svg?token=4C091RHXC3
109
+ [coverage]: https://codecov.io/gh/ryancyq/mime_actor
110
+ [maintainability_badge]: https://api.codeclimate.com/v1/badges/06689606dc3f3945dc1b/maintainability
111
+ [maintainability]: https://codeclimate.com/github/ryancyq/mime_actor/maintainability
112
+
113
+ [doc_mime_actor]: https://rubydoc.info/gems/mime_actor
114
+ [doc_action_controller]: https://rubydoc.info/gems/actionpack/ActionController/Metal
115
+ [doc_action_controller_mime_responds]: https://rubydoc.info/gems/actionpack/ActionController/MimeResponds
116
+ [doc_comparison]: https://github.com/ryancyq/mime_actor/blob/main/COMPARE.md
@@ -10,6 +10,12 @@ require "abstract_controller/rendering"
10
10
  require "action_controller/metal/mime_responds"
11
11
 
12
12
  module MimeActor
13
+ # # MimeActor Action
14
+ #
15
+ # Action is the recommended Module to be included in ActionController.
16
+ #
17
+ # Provides intuitive way of action rendering for a specific MIME type with rescue handlers.
18
+ #
13
19
  module Action
14
20
  extend ActiveSupport::Concern
15
21
 
@@ -21,6 +27,8 @@ module MimeActor
21
27
  include Rescue
22
28
  include Logging
23
29
 
30
+ ##
31
+ # The core logic where rendering logics are collected as Proc through configuration and passed over to ActionController::MimeResponds
24
32
  def start_scene(action)
25
33
  action = action&.to_sym
26
34
  formats = acting_scenes.fetch(action, Set.new)
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  require "active_support/concern"
4
6
  require "active_support/configurable"
5
7
  require "active_support/isolated_execution_state" # required by active_support/logger
@@ -7,6 +9,9 @@ require "active_support/logger"
7
9
  require "active_support/tagged_logging"
8
10
 
9
11
  module MimeActor
12
+ # # MimeActor Logging
13
+ #
14
+ # Provides a configurable logger.
10
15
  module Logging
11
16
  extend ActiveSupport::Concern
12
17
 
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  require "mime_actor/stage"
4
6
  require "mime_actor/validator"
5
7
 
@@ -9,6 +11,10 @@ require "active_support/core_ext/module/attribute_accessors"
9
11
  require "active_support/core_ext/string/inflections"
10
12
 
11
13
  module MimeActor
14
+ # # MimeActor Rescue
15
+ #
16
+ # Simillar to ActionController::Rescue but with additional filtering logic on Action/Format.
17
+ #
12
18
  module Rescue
13
19
  extend ActiveSupport::Concern
14
20
 
@@ -20,6 +26,15 @@ module MimeActor
20
26
  end
21
27
 
22
28
  module ClassMethods
29
+ ##
30
+ # Registers a rescue handler for the given error classes with action/format filter
31
+ #
32
+ # rescue_actor_from StandardError, format: :json, action: :show do |ex|
33
+ # render status: :bad_request, json: { error: ex.message }
34
+ # end
35
+ #
36
+ # rescue_actor_from StandardError, format: :html, with: :handle_html_error
37
+ #
23
38
  def rescue_actor_from(*klazzes, action: nil, format: nil, with: nil, &block)
24
39
  raise ArgumentError, "error filter is required" if klazzes.empty?
25
40
 
@@ -58,6 +73,9 @@ module MimeActor
58
73
  end
59
74
  end
60
75
 
76
+ ##
77
+ # Resolve the error provided with the registered handlers.
78
+ # The handled error will be returned to indicate successful handling
61
79
  def rescue_actor(error, action: nil, format: nil, context: self, visited: [])
62
80
  return if visited.include?(error)
63
81
 
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  require "mime_actor/errors"
4
6
  require "mime_actor/validator"
5
7
 
@@ -9,6 +11,15 @@ require "active_support/core_ext/array/wrap"
9
11
  require "active_support/core_ext/module/attribute_accessors"
10
12
 
11
13
  module MimeActor
14
+ # # MimeActor Scene
15
+ #
16
+ # Scene provides configuration for Action + Format definitions
17
+ #
18
+ # compose_scene :html, on: :index
19
+ # compose_scene :html, :json , on: [:index, :show]
20
+ #
21
+ # NOTE: Calling the same action/format multiple times will overwrite previous Action + Format definitions.
22
+ #
12
23
  module Scene
13
24
  extend ActiveSupport::Concern
14
25
 
@@ -19,6 +30,10 @@ module MimeActor
19
30
  end
20
31
 
21
32
  module ClassMethods
33
+ ##
34
+ # Register Action + Format definitions.
35
+ #
36
+ # For each unique action being registered, it will have a corresponding method being defined.
22
37
  def compose_scene(*options)
23
38
  config = options.extract_options!
24
39
  validate!(:formats, options)
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  require "mime_actor/errors"
4
6
  require "mime_actor/logging"
5
7
 
@@ -7,6 +9,10 @@ require "active_support/concern"
7
9
  require "active_support/core_ext/module/attribute_accessors"
8
10
 
9
11
  module MimeActor
12
+ # # MimeActor Stage
13
+ #
14
+ # Stage provides helpers for actor lookup and invocation.
15
+ #
10
16
  module Stage
11
17
  extend ActiveSupport::Concern
12
18
 
@@ -17,6 +23,8 @@ module MimeActor
17
23
  end
18
24
 
19
25
  module ClassMethods
26
+ ##
27
+ # Determine if the name belongs to a public instance method excluding methods inherited from ancesstors
20
28
  def actor?(actor_name)
21
29
  # exclude public methods from ancestors
22
30
  found = public_instance_methods(false).include?(actor_name.to_sym)
@@ -27,7 +35,11 @@ module MimeActor
27
35
  found
28
36
  end
29
37
 
38
+ ##
39
+ # Wraps the given block with lambda, rescue any error raised from the block via #rescue_actor if defined, otherwise, error will be re-raised
30
40
  def dispatch_cue(action: nil, format: nil, context: self, &block)
41
+ raise ArgumentError, "block must be provided" unless block_given?
42
+
31
43
  lambda do
32
44
  context.instance_exec(&block)
33
45
  rescue StandardError => e
@@ -36,6 +48,10 @@ module MimeActor
36
48
  end
37
49
  end
38
50
 
51
+ ##
52
+ # Call the actor method if defined, supports passing arguments to the actor method.
53
+ #
54
+ # If a block is given, the result from the actor method will be yieled to the block
39
55
  def cue_actor(actor_name, *args)
40
56
  unless self.class.actor?(actor_name)
41
57
  raise MimeActor::ActorNotFound, actor_name if raise_on_missing_actor
@@ -1,10 +1,23 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  require "active_support/concern"
4
6
  require "set" # required by mime_type with ruby <= 3.1
5
7
  require "action_dispatch/http/mime_type"
6
8
 
7
9
  module MimeActor
10
+ # # MimeActor Validator
11
+ #
12
+ # Validator provides validation rules for action, format, and rescue handlers by default.
13
+ #
14
+ # # raise error when rule is violated
15
+ # validate!(:action, action_param)
16
+ #
17
+ # # return the error when rule is violated
18
+ # ex = validate_action(action_param)
19
+ # raise ex if error
20
+ #
8
21
  module Validator
9
22
  extend ActiveSupport::Concern
10
23
 
@@ -13,6 +26,8 @@ module MimeActor
13
26
  end
14
27
 
15
28
  module ClassMethods
29
+ ##
30
+ # Raise the error returned by validator if present.
16
31
  def validate!(rule, *args)
17
32
  validator = "validate_#{rule}"
18
33
  raise NameError, "Validator not found, got: #{validator}" unless respond_to?(validator, true)
@@ -21,21 +36,29 @@ module MimeActor
21
36
  raise error if error
22
37
  end
23
38
 
39
+ ##
40
+ # validate :action must be a Symbol
24
41
  def validate_action(unchecked)
25
42
  ArgumentError.new("action must be a Symbol") unless unchecked.is_a?(Symbol)
26
43
  end
27
44
 
45
+ ##
46
+ # validate :actions must be an Array of Symbol
28
47
  def validate_actions(unchecked)
29
48
  rejected = unchecked.reject { |action| action.is_a?(Symbol) }
30
49
  NameError.new("invalid actions, got: #{rejected.join(", ")}") if rejected.size.positive?
31
50
  end
32
51
 
52
+ ##
53
+ # validate :format must be a Symbol + a valid MIME type
33
54
  def validate_format(unchecked)
34
55
  return ArgumentError.new("format must be a Symbol") unless unchecked.is_a?(Symbol)
35
56
 
36
57
  NameError.new("invalid format, got: #{unchecked}") unless scene_formats.include?(unchecked)
37
58
  end
38
59
 
60
+ ##
61
+ # validate :formats must be an Array of Symbol which each of them is a valid MIME type
39
62
  def validate_formats(unchecked)
40
63
  unfiltered = unchecked.to_set
41
64
  filtered = unfiltered & scene_formats
@@ -44,6 +67,8 @@ module MimeActor
44
67
  NameError.new("invalid formats, got: #{rejected.join(", ")}") if rejected.size.positive?
45
68
  end
46
69
 
70
+ ##
71
+ # validate :with or &block must be provided + :with must be a Symbol or Proc
47
72
  def validate_with(unchecked, block)
48
73
  if unchecked.present? && block.present?
49
74
  return ArgumentError.new("provide either the with: keyword argument or a block")
@@ -12,7 +12,7 @@ module MimeActor
12
12
  module VERSION
13
13
  MAJOR = 0
14
14
  MINOR = 5
15
- BUILD = 1
15
+ BUILD = 3
16
16
  PRE = nil
17
17
 
18
18
  STRING = [MAJOR, MINOR, BUILD, PRE].compact.join(".")
data/lib/mime_actor.rb CHANGED
@@ -1,5 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+ # :include: ../README.md
5
+
3
6
  require "mime_actor/version"
4
7
  require "mime_actor/errors"
5
8
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mime_actor
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.1
4
+ version: 0.5.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Chang
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-06-28 00:00:00.000000000 Z
11
+ date: 2024-06-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: actionpack
@@ -63,6 +63,7 @@ files:
63
63
  - ".rspec"
64
64
  - ".rubocop.yml"
65
65
  - ".ruby-version"
66
+ - COMPARE.md
66
67
  - LICENSE
67
68
  - README.md
68
69
  - Rakefile
@@ -103,5 +104,5 @@ requirements: []
103
104
  rubygems_version: 3.5.9
104
105
  signing_key:
105
106
  specification_version: 4
106
- summary: action rendering and rescue with mime type via configuration in actionpack
107
+ summary: Action Render + Rescue handlers for different MIME types in Rails
107
108
  test_files: []