operate 0.1.0 → 0.1.1

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
  SHA1:
3
- metadata.gz: d93185f6ff1d022b5511ba6f6fbd2e815e27eaf1
4
- data.tar.gz: d0ba09ef7bb5723dc5e0302847dd0c635c28191d
3
+ metadata.gz: e4ae06d376016ee482b1fe2c0fb7d15304f96f77
4
+ data.tar.gz: '01248b745836660db7dedb802bf25de16d7c77a8'
5
5
  SHA512:
6
- metadata.gz: ee4756b459c0db03be97b7e581ad4e7d27fbc9202bc5e661f393f55f806f66cedd489ea9d25b4ec89ad91b5f0f56c6cdc48bcfd4d627e04c0c5b8fcc7ccee943
7
- data.tar.gz: 8daae04166fe135d2f4e70b3d37946bcbb24291834a91371b87d44cc55e999f0f5b87d43379ad115da0840e583376f4a5825405072b29179e3c87edc1ccb8f2d
6
+ metadata.gz: 4b503d5be289f23dce63009daf120dedad7081ad42993d6934314d051f0dc2b9f0c8e68d21da81fe458fc2335e61384fa100b4cdfaa7e06309882de0970906fb
7
+ data.tar.gz: 8f3c185e0a3b2f92e0d1a8384d8f91363f5562ad6028a6337cbe979fe73d9fdcfdf381a7777d7be8c8f34a85e0ab23624163cf5b8b91c2e4cc03eb7aad00c342
data/.gitignore CHANGED
@@ -7,6 +7,6 @@
7
7
  /pkg/
8
8
  /spec/reports/
9
9
  /tmp/
10
-
10
+ /operate*gem
11
11
  # rspec failure tracking
12
12
  .rspec_status
data/CHANGELOG.md ADDED
@@ -0,0 +1,15 @@
1
+ # Operate Changelog
2
+
3
+
4
+ ## [0.1.1] - October 27, 2017
5
+
6
+ - dependency on ActiveSupport::Concern removed
7
+ - ActiveRecord no longer required: if ActiveRecord is not available, `Operate::Command#transaction(&block)` is disabled
8
+
9
+
10
+ ## 0.1.0 - September 27, 2017
11
+
12
+ - Initial release
13
+
14
+
15
+ [0.1.1]: https://github.com/tomichj/operate/compare/0.1.0...0.1.1
data/README.md CHANGED
@@ -2,21 +2,29 @@
2
2
 
3
3
  Operate is a gem to help create [service objects].
4
4
 
5
- Use Operate to __remove all business logic from your controller and model__, subsuming it in an Operate-based
6
- class that represents your processes. Examples might be: a user addition, a post addition, or adding a comment.
5
+ [![Gem Version](https://badge.fury.io/rb/operate.svg)](https://badge.fury.io/rb/operate) ![Build status](https://travis-ci.org/tomichj/operate.svg?branch=master) ![Code Climate](https://codeclimate.com/github/tomichj/operate/badges/gpa.svg)
6
+
7
+ Use Operate to __remove business logic from your controller and model__, subsuming it in Operate-based
8
+ "service" object that represents your processes. Examples might be: a user addition, a post addition,
9
+ or adding a comment.
7
10
 
8
11
  Service objects can out factor behavior that would bloat models or controllers, and is a useful step to patterns
9
12
  like Strategy and Command.
10
13
 
11
- Operate is in the very earliest stages of development. Additional features will be added. The core API
12
- exposed via `Operate::Command` is solid and no changes are in the words.
14
+ Service objects are not a new concept, and extracting controller bloat to service objects is a common
15
+ refactoring pattern. This [Arkency blog post] describes extracting service objects using SimpleDelegator, a
16
+ useful pattern. Operate can assist you with process, further refining it: rather than raising exceptions in your
17
+ service object, and rescuing exceptions in your controller, we broadcast and subscribe to events.
18
+
19
+ Operate is in the very earliest stages of development. Additional features will be added. The current API
20
+ exposed via `Operate::Command`, however, is solid and no breaking changes there are anticipated.
13
21
 
14
22
 
15
23
  ## Dependencies
16
24
 
17
- Operate requires:
18
- * `ActiveRecord` 4.2 or greater
19
- * `ActiveSupport` 4.2 or greater
25
+ Operate requires only `ActiveSupport` 4.2 or greater.
26
+
27
+ Additionally, if ActiveRecord is available, transactions are supported. There is no explicit support for other ORMs.
20
28
 
21
29
  It's not required, but a form object library like [Reform] is recommended. Reform is used in the examples below.
22
30
 
@@ -44,16 +52,17 @@ Just `include Operate::Command` in your class. Operate's api provides:
44
52
 
45
53
  Methods used in your service class:
46
54
  * `self#call(*args, &block)` will initialize your service class with *args and invoke #call
47
- * `#broadcast(:event, *args)` that will broadcast an event to a subscriber
48
- * `#transaction(&block)` that wraps a block inside a transaction
55
+ * `#broadcast(:event, *args)` will broadcast an event to a subscriber (see `on` below)
56
+ * `#transaction(&block)` wraps a block with an `ActiveRecord::Base.transaction` (only if ActiveRecord is available)
49
57
 
50
- Methods used by clients of your service class:
58
+ Methods used by clients (normally a controller) of your service class:
51
59
  * `#on(*events, &block)` that subscribe to an event or events, and provide a block to handle that event
52
60
 
53
61
 
54
62
  An example service:
55
63
 
56
64
  ```ruby
65
+ # put in app/services, app/commands, or something like that
57
66
  class UserAddition
58
67
  include Operate::Command
59
68
 
@@ -63,7 +72,7 @@ class UserAddition
63
72
  end
64
73
 
65
74
  def call
66
- return broadcast(:invalid) unless @form.validate(@params)
75
+ return broadcast(:invalid) unless @form.validate(@params[:user])
67
76
 
68
77
  transaction do
69
78
  create_user
@@ -102,6 +111,8 @@ class UserController < ApplicationController
102
111
  end
103
112
  ```
104
113
 
114
+ Note: this example does not use [Strong Parameters] as [Reform] provides an explicit form property layout.
115
+
105
116
 
106
117
  ## Credit
107
118
 
@@ -117,11 +128,20 @@ This project is intended to be a safe, welcoming space for collaboration, and co
117
128
  expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
118
129
 
119
130
 
131
+ ## Contributors
132
+
133
+ Many thanks to:
134
+
135
+ * [k3rni](https://github.com/k3rni) made ActiveRecord dependency optional
136
+
137
+
120
138
  ## License
121
139
 
122
140
  The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
123
141
 
124
142
  [service objects]: https://gist.github.com/blaix/5764401
143
+ [arkency blog post]: http://blog.arkency.com/2015/05/extract-a-service-object-using-simpledelegator/
125
144
  [Reform]: http://trailblazer.to/gems/reform/index.html
145
+ [String Parameters]: https://github.com/rails/strong_parameters
126
146
  [rectify]: https://github.com/andypike/rectify
127
147
  [wisper]: https://github.com/krisleech/wisper
@@ -9,13 +9,15 @@ module Operate
9
9
  #
10
10
  module Command
11
11
  include Operate::Pubsub::Publisher
12
- extend ActiveSupport::Concern
13
12
 
14
- module ClassMethods
13
+ class Error < StandardError; end
14
+
15
+ def self.included(target)
16
+ target.extend ClassMethods
17
+ end
15
18
 
16
- #
17
- # Call will initialize the class with *args and invoke `call` with no parameters.
18
- #
19
+ module ClassMethods
20
+ # Call will initialize the class with *args and invoke instance method `call` with no arguments
19
21
  def call(*args, &block)
20
22
  command = new(*args)
21
23
  command.evaluate(&block) if block_given?
@@ -24,7 +26,13 @@ module Operate
24
26
  end
25
27
 
26
28
  def transaction(&block)
27
- ActiveRecord::Base.transaction(&block) if block_given?
29
+ return unless block_given?
30
+
31
+ if defined?(ActiveRecord)
32
+ ::ActiveRecord::Base.transaction(&block)
33
+ else
34
+ raise Error, 'Transactions are supported only with ActiveRecord'
35
+ end
28
36
  end
29
37
 
30
38
  def evaluate(&block)
@@ -1,3 +1,3 @@
1
1
  module Operate
2
- VERSION = "0.1.0"
2
+ VERSION = '0.1.1'
3
3
  end
data/operate.gemspec CHANGED
@@ -9,8 +9,8 @@ Gem::Specification.new do |spec|
9
9
  spec.authors = ['Justin Tomich']
10
10
  spec.email = ['tomichj@gmail.com']
11
11
 
12
- spec.summary = 'An operation object.'
13
- spec.description = ''
12
+ spec.summary = 'Create service objects with Operate.'
13
+ spec.description = 'Create service objects with Operate.'
14
14
  spec.homepage = 'https://github.com/tomichj/operate'
15
15
  spec.license = 'MIT'
16
16
 
@@ -29,10 +29,9 @@ Gem::Specification.new do |spec|
29
29
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
30
30
  spec.require_paths = ["lib"]
31
31
 
32
- spec.add_dependency 'activesupport', '>= 4.2.0'
33
- spec.add_dependency 'activerecord', '>= 4.2.0'
34
-
35
32
  spec.add_development_dependency 'bundler', '~> 1.14'
36
33
  spec.add_development_dependency 'rake', '~> 10.0'
37
34
  spec.add_development_dependency 'rspec', '~> 3.0'
35
+ spec.add_development_dependency 'activerecord', '>= 4.2.0'
36
+ spec.add_development_dependency 'sqlite3'
38
37
  end
metadata CHANGED
@@ -1,86 +1,86 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: operate
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Tomich
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-09-27 00:00:00.000000000 Z
11
+ date: 2017-10-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: activesupport
14
+ name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 4.2.0
20
- type: :runtime
19
+ version: '1.14'
20
+ type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ">="
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 4.2.0
26
+ version: '1.14'
27
27
  - !ruby/object:Gem::Dependency
28
- name: activerecord
28
+ name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ">="
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 4.2.0
34
- type: :runtime
33
+ version: '10.0'
34
+ type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ">="
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 4.2.0
40
+ version: '10.0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: bundler
42
+ name: rspec
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '1.14'
47
+ version: '3.0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '1.14'
54
+ version: '3.0'
55
55
  - !ruby/object:Gem::Dependency
56
- name: rake
56
+ name: activerecord
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - "~>"
59
+ - - ">="
60
60
  - !ruby/object:Gem::Version
61
- version: '10.0'
61
+ version: 4.2.0
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - "~>"
66
+ - - ">="
67
67
  - !ruby/object:Gem::Version
68
- version: '10.0'
68
+ version: 4.2.0
69
69
  - !ruby/object:Gem::Dependency
70
- name: rspec
70
+ name: sqlite3
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - "~>"
73
+ - - ">="
74
74
  - !ruby/object:Gem::Version
75
- version: '3.0'
75
+ version: '0'
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: '3.0'
83
- description: ''
82
+ version: '0'
83
+ description: Create service objects with Operate.
84
84
  email:
85
85
  - tomichj@gmail.com
86
86
  executables: []
@@ -90,6 +90,7 @@ files:
90
90
  - ".gitignore"
91
91
  - ".rspec"
92
92
  - ".travis.yml"
93
+ - CHANGELOG.md
93
94
  - CODE_OF_CONDUCT.md
94
95
  - Gemfile
95
96
  - LICENSE.txt
@@ -127,5 +128,5 @@ rubyforge_project:
127
128
  rubygems_version: 2.6.11
128
129
  signing_key:
129
130
  specification_version: 4
130
- summary: An operation object.
131
+ summary: Create service objects with Operate.
131
132
  test_files: []