actionizer 0.3.0 → 0.4.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
  SHA1:
3
- metadata.gz: 0c2200e547ac2adeb77d8ab2394037f7006550c5
4
- data.tar.gz: d8865ebe73d8d765f8452b31db58ed24b804f69c
3
+ metadata.gz: 7d164afc660031126496b00a38e931702afd5814
4
+ data.tar.gz: ddd5bf72049506461b926b387355dffadfd4dc42
5
5
  SHA512:
6
- metadata.gz: cb086adc3bb250d211d585f92379ca3fa9292c4b5336676e49beb2cf59c0f18d2274f7137cd1480e2ef82a6f8854c20467b8d453788cb36fda5da85b0e134f94
7
- data.tar.gz: 63a124f87db6bd8ee1c6aa2808adfbe6a6cb82cfdf214ab56c9a7191a8e9f3e82e4f21df88f7bafd4cb2e475b3a99e52ad0adc875bfd488e82b6d6c11b9aead5
6
+ metadata.gz: e335eb30321f19c246d4087b6ad7aa824efbca9971b1aa1a0dc42c9c2d9bfe2fca5d9ceb59160aef88d49b8961c6a2a19fcad1e84f4d7d8ed7d9f7aa41017ebe
7
+ data.tar.gz: 9fc717ebadfb532442bc080ff3ff49300611ed1ef3a07eabad9c33f498ee7c074e7653e352a363576fd730e228af0447ab59ab8208ee6b43b77e220caef78daa
data/README.md CHANGED
@@ -24,82 +24,81 @@ Or install it yourself as:
24
24
 
25
25
  ## Usage
26
26
 
27
- Here's how you define an Action:
27
+ Include `Actionizer` in your class and define an instance method. That instance method will be automatically invoked when you call the class method of the same name. Any Action defined with `Actionizer` will automatically return a hash-like result you can check for `success?` or `failure?`.
28
28
 
29
- ```ruby
30
- module Action
31
- module Users
32
-
33
- class Create
34
- include Actionizer
29
+ Inputs are available on the `input` instance variable. Use `output` to set any variables you want returned in the result.
35
30
 
36
- def call
37
- # Do stuff here
38
- output.user = user
39
- end
40
- end
31
+ ```ruby
32
+ class CreateUser
33
+ include Actionizer
41
34
 
35
+ def call
36
+ # Some validation here...
37
+ output.user = User.create(name: input.name)
42
38
  end
43
39
  end
44
40
  ```
45
41
 
46
- You can immediately stop execution with the `fail!` method
42
+ Actions are successful by default:
47
43
  ```ruby
48
- module Action
49
- module Users
44
+ result = SuccessfulAction.call(id: 1234)
50
45
 
51
- class Delete
52
- include Actionizer
46
+ result.success?
47
+ #=> true
48
+ result.failure?
49
+ #=> false
50
+ ```
53
51
 
54
- def call
55
- # Possibly failing code here
56
- fail!(error: "Nope, didn't work") if failure_condition
52
+ You can immediately stop execution with the `fail!` method.
53
+ ```ruby
54
+ class DeleteAccount
55
+ include Actionizer
57
56
 
58
- # This code never runs
59
- output.foo = 'bar'
60
- end
61
- end
57
+ def run
58
+ # Possibly failing code here
59
+ fail!(error: "Nope, didn't work") if failure_condition
62
60
 
61
+ # This code never runs
62
+ output.foo = 'bar'
63
63
  end
64
64
  end
65
65
  ```
66
66
 
67
- Here's how you invoke it:
67
+ When an action fails with `fail!`, the result it returns will return false for `success?` and true for `failure?`.
68
68
  ```ruby
69
- module Action
70
- module Users
69
+ result = FailingAction.call(id: 1234)
71
70
 
72
- class Onboard
73
- include Actionizer
71
+ result.success?
72
+ #=> false
73
+ result.failure?
74
+ #=> true
75
+ ```
74
76
 
75
- def call
76
- result = Action::Users::Create.call(name: name, email: email)
77
- fail!(error: result.error) if result.failure?
77
+ The most common way to use Actionizer is to compose small pieces of functionality (which can themselves be Actions) into larger pieces of functionality to give that sequence of Actions a name and simple interface.
78
+ ```ruby
79
+ class OnboardUser
80
+ include Actionizer
78
81
 
79
- result = Action::Users::SendWelcomeEmail.call(name: name, email: email)
80
- fail!(error: result.error) if result.failure?
81
- end
82
- end
82
+ def call
83
+ result = CreateUser.call(name: input.name, email: input.email)
84
+ fail!(error: result.error) if result.failure?
83
85
 
86
+ result = SendWelcomeEmail.deliver_now(name: input.name, email: input.email)
87
+ fail!(error: result.error) if result.failure?
84
88
  end
85
89
  end
86
90
  ```
87
91
 
88
- This pattern is so common, there's a shorthand: `call_and_check_failure!`
89
- ```ruby
90
- module Action
91
- module Users
92
92
 
93
- class Onboard
94
- include Actionizer
95
-
96
- def call
97
- # This code is identical to the example above
98
- call_and_check_failure!(Action::Users::Create, name: name, email: email)
99
- call_and_check_failure!(Action::Users::SendWelcomeEmail, name: name, email: email)
100
- end
101
- end
93
+ This pattern is so common, there's a shorthand: `<METHOD>_or_fail`. It works for any instance method defined on the class you specify.
94
+ ```ruby
95
+ class OnboardUser
96
+ include Actionizer
102
97
 
98
+ def call
99
+ # This code is identical to the example above
100
+ call_or_fail(CreateUser, name: input.name, email: input.email)
101
+ deliver_now_or_fail(SendWelcomeEmail, name: input.name, email: input.email)
103
102
  end
104
103
  end
105
104
  ```
data/actionizer.gemspec CHANGED
@@ -31,7 +31,7 @@ Gem::Specification.new do |spec|
31
31
  spec.add_development_dependency 'bundler', '~> 1.11'
32
32
  spec.add_development_dependency 'rake', '~> 10.0'
33
33
  spec.add_development_dependency 'rspec', '~> 3.0'
34
- spec.add_development_dependency 'byebug', '~> 8.2'
34
+ spec.add_development_dependency 'pry-byebug', '~> 3.3'
35
35
  spec.add_development_dependency 'rubocop', '~> 0.37'
36
36
  spec.add_development_dependency 'simplecov', '~> 0.11'
37
37
  end
data/lib/actionizer.rb CHANGED
@@ -6,17 +6,25 @@ module Actionizer
6
6
  attr_reader :input, :output
7
7
 
8
8
  def self.included(base)
9
- base.class_eval do
10
- extend ClassMethods
11
- end
9
+ base.extend(ClassMethods)
12
10
  end
13
11
 
14
12
  module ClassMethods
15
- def call(inputs = {})
16
- new(inputs).tap(&:call).output
13
+ def method_missing(method_name, *args, &block)
14
+ instance = new(*args)
15
+
16
+ if instance.respond_to?(method_name)
17
+ instance.tap(&method_name).output
18
+ else
19
+ super
20
+ end
17
21
  rescue Actionizer::Failure => af
18
22
  af.output
19
23
  end
24
+
25
+ def respond_to_missing?(method_name, include_private = false)
26
+ new.respond_to?(method_name, include_private)
27
+ end
20
28
  end
21
29
 
22
30
  def initialize(initial_input = {})
@@ -32,14 +40,23 @@ module Actionizer
32
40
  raise Actionizer::Failure.new('Failed!', output)
33
41
  end
34
42
 
35
- def call_and_check_failure!(action_class, params = {})
43
+ # Allows you to call *_or_fail
44
+ def method_missing(method_name, *args, &block)
45
+ return super unless method_name.to_s.end_with?('_or_fail')
46
+
47
+ action_class, params = *args
48
+
36
49
  unless action_class.include? Actionizer
37
50
  raise ArgumentError, "#{action_class.name} must include Actionizer"
38
51
  end
39
52
 
40
- result = action_class.call(params)
53
+ result = action_class.send(method_name.to_s.chomp('_or_fail'), params)
41
54
  fail!(error: result.error) if result.failure?
42
55
 
43
56
  result
44
57
  end
58
+
59
+ def respond_to_missing?(method_name, _include_private = false)
60
+ method_name.to_s.end_with?('_or_fail')
61
+ end
45
62
  end
@@ -1,3 +1,3 @@
1
1
  module Actionizer
2
- VERSION = '0.3.0'
2
+ VERSION = '0.4.0'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: actionizer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Nichols
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-03-03 00:00:00.000000000 Z
11
+ date: 2016-04-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: hashie
@@ -67,19 +67,19 @@ dependencies:
67
67
  - !ruby/object:Gem::Version
68
68
  version: '3.0'
69
69
  - !ruby/object:Gem::Dependency
70
- name: byebug
70
+ name: pry-byebug
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: '8.2'
75
+ version: '3.3'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: '8.2'
82
+ version: '3.3'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: rubocop
85
85
  requirement: !ruby/object:Gem::Requirement