swamp-rails-actions 1.0.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: f77d3514fb0654afcbf11ad9e4d24a5a28c14ee3940792589f4821c4e504f8cd
4
+ data.tar.gz: f9a80f1ed3d7c587a18ecfd14420a3515de8677afd7156a289c253dcd5c52be9
5
+ SHA512:
6
+ metadata.gz: 3ab57d6cf5c3afaf6c0f09df82633f8c52b27b11c72084b7da07fb22c242b82d1c95bac51b7dfdb785aa59a16380aa0b597c9a33bc535624f175a8d4ae9faf5d
7
+ data.tar.gz: c0f2ee2ffa56db9a1d06df59546b0ec6f1c86af4d56358b699e906369f4fa6419f8478c3563675512566a71ee04e6baeba0eb968352c7539a1c34900d631be72
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Swamp
4
+ end
5
+
6
+ require_relative 'swamp/rails_actions/action'
7
+ require_relative 'swamp/rails_actions/controller'
@@ -0,0 +1,127 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative './action/flash'
4
+ require_relative './action/parameters'
5
+ require_relative './action/routes'
6
+
7
+ module Swamp
8
+ module Action
9
+ def self.included(base)
10
+ base.extend ClassMethods
11
+ base.include Swamp::Action::Parameters
12
+ base.include Swamp::Action::Routes
13
+ base.include Swamp::Action::Flash
14
+ end
15
+
16
+ class Result
17
+ attr_reader :template, :redirection_path, :redirection_options
18
+
19
+ def render(template)
20
+ @template = template
21
+ end
22
+
23
+ def redirect_to(path, **options)
24
+ @redirection_path = path
25
+ @redirection_options = options
26
+ end
27
+
28
+ def prepare!(payload)
29
+ exposures.merge!(payload)
30
+ self
31
+ end
32
+
33
+ def redirect?
34
+ !redirection_path.nil?
35
+ end
36
+
37
+ def render?
38
+ !template.nil?
39
+ end
40
+
41
+ def exposures
42
+ @exposures ||= Hash[]
43
+ end
44
+
45
+ protected
46
+
47
+ def method_missing(method_name, *)
48
+ exposures.fetch(method_name) { super }
49
+ end
50
+
51
+ def respond_to_missing?(method_name, _include_all)
52
+ exposures.key?(method_name.to_sym) ? true : super
53
+ end
54
+ end
55
+
56
+ def call(args = Hash[])
57
+ prepare(args)
58
+
59
+ catch :done do
60
+ _call
61
+ end
62
+
63
+ finalize(args)
64
+ end
65
+
66
+ def _call; end
67
+
68
+ private
69
+
70
+ def prepare(kwargs)
71
+ @request = kwargs[:request]
72
+ @__result = ::Swamp::Action::Result.new
73
+ end
74
+
75
+ def expose(*names)
76
+ names.each do |name|
77
+ send(name) if self.class.exposures.include?(name)
78
+ end
79
+ end
80
+
81
+ def finalize(*)
82
+ @__result.prepare!(_exposures)
83
+ end
84
+
85
+ def _exposures
86
+ Hash[].tap do |result|
87
+ self.class.exposures.each do |name, ivar|
88
+ result[name] = respond_to?(name) ? send(name) : instance_variable_get(ivar)
89
+ end
90
+ end
91
+ end
92
+
93
+ def render(template)
94
+ @__result.render(template)
95
+ throw :done
96
+ end
97
+
98
+ def redirect_to(path, **options)
99
+ @__result.redirect_to(path, options)
100
+ throw :done
101
+ end
102
+
103
+ module ClassMethods
104
+ attr_reader :exposures
105
+
106
+ def self.extended(interactor)
107
+ interactor.class_eval do
108
+ self.exposures = {}
109
+ end
110
+ end
111
+
112
+ def call(args = Hash[])
113
+ new.call(args)
114
+ end
115
+
116
+ def expose(*instance_variable_names)
117
+ instance_variable_names.each do |name|
118
+ exposures[name.to_sym] = "@#{name}"
119
+ end
120
+ end
121
+
122
+ protected
123
+
124
+ attr_writer :exposures
125
+ end
126
+ end
127
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Swamp
4
+ module Action
5
+ module Flash
6
+ def self.included(base)
7
+ base.expose :flash
8
+ end
9
+
10
+ def flash_alert!(message)
11
+ flash[:alert] = message
12
+ end
13
+
14
+ def flash_notice!(message)
15
+ flash[:notice] = message
16
+ end
17
+
18
+ def flash
19
+ @flash ||= Hash[]
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Swamp
4
+ module Action
5
+ module Parameters
6
+ def self.included(base)
7
+ base.extend ClassMethods
8
+ base.expose :validation_result
9
+ end
10
+
11
+ private
12
+
13
+ attr_reader :input, :validation_result
14
+
15
+ def prepare(params)
16
+ super
17
+ return true if self.class.param_class.nil?
18
+
19
+ @validation_result = self.class.param_class.call(params)
20
+ @input = validation_result.output
21
+ end
22
+
23
+ def method_missing(method_name, *)
24
+ input.fetch(method_name.to_sym) { super }
25
+ end
26
+
27
+ def respond_to_missing?(method_name, _include_all)
28
+ input.key?(method_name.to_sym) ? true : super
29
+ end
30
+
31
+ module ClassMethods
32
+ attr_reader :param_class
33
+
34
+ def params(&block)
35
+ @param_class = Dry::Validation.Form do
36
+ instance_exec(&block)
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Swamp::Action
4
+ module Routes
5
+ def router
6
+ @router ||= Router.new
7
+ end
8
+
9
+ def path(name, options = Hash[])
10
+ router.send(:"#{name}_path", router_default_url_options.merge(options))
11
+ end
12
+
13
+ def url(name, options = Hash[])
14
+ router.send(:"#{name}_url", router_default_url_options.merge(options))
15
+ end
16
+
17
+ def router_default_url_options
18
+ Hash[].tap do |opts|
19
+ opts[:host] = @request.host if @request
20
+ end
21
+ end
22
+
23
+ class Router
24
+ include Rails.application.routes.url_helpers
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Swamp
4
+ module Controller
5
+ def self.included(base)
6
+ base.extend ClassMethods
7
+ end
8
+
9
+ def action!(klass, **kwargs)
10
+ result = klass.new.call(params.to_unsafe_h.merge(request: request, **kwargs))
11
+
12
+ setup_exposures!(klass, result)
13
+
14
+ if result.render?
15
+ render_result(result, klass)
16
+ elsif result.redirect?
17
+ redirect_result(result, klass)
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ def render_result(result, klass)
24
+ setup_flash_now(result, klass)
25
+ render result.template
26
+ end
27
+
28
+ def redirect_result(result, klass)
29
+ setup_flash(result, klass)
30
+ redirect_to result.redirection_path, result.redirection_options
31
+ end
32
+
33
+ def setup_exposures!(klass, result)
34
+ klass.exposures.each do |key, value|
35
+ instance_variable_set(value, result.exposures[key])
36
+ end
37
+ end
38
+
39
+ def setup_flash_now(result, klass)
40
+ return unless klass.exposures.key?(:flash)
41
+
42
+ result.flash.each do |type, message|
43
+ flash.now[type] = message
44
+ end
45
+ end
46
+
47
+ def setup_flash(result, klass)
48
+ return unless klass.exposures.key?(:flash)
49
+
50
+ result.flash.each do |type, message|
51
+ flash[type] = message
52
+ end
53
+ end
54
+
55
+ module ClassMethods
56
+ def action!(name, klass, *args)
57
+ define_method name do
58
+ input = Hash[args.map { |k| [k, send(k)] }]
59
+ action! klass, **input
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
metadata ADDED
@@ -0,0 +1,104 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: swamp-rails-actions
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Marion Duprey
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-05-31 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: dry-core
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: dry-validation
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '5'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '5'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '12'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '12'
69
+ description: Split your controllers to actions
70
+ email: marion@lynary.me
71
+ executables: []
72
+ extensions: []
73
+ extra_rdoc_files: []
74
+ files:
75
+ - lib/swamp-rails-actions.rb
76
+ - lib/swamp/rails_actions/action.rb
77
+ - lib/swamp/rails_actions/action/flash.rb
78
+ - lib/swamp/rails_actions/action/parameters.rb
79
+ - lib/swamp/rails_actions/action/routes.rb
80
+ - lib/swamp/rails_actions/controller.rb
81
+ homepage:
82
+ licenses:
83
+ - MIT
84
+ metadata: {}
85
+ post_install_message:
86
+ rdoc_options: []
87
+ require_paths:
88
+ - lib
89
+ required_ruby_version: !ruby/object:Gem::Requirement
90
+ requirements:
91
+ - - ">="
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ required_rubygems_version: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - ">="
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ requirements: []
100
+ rubygems_version: 3.0.3
101
+ signing_key:
102
+ specification_version: 4
103
+ summary: Split your controllers to actions
104
+ test_files: []