operate 0.1.0 → 0.1.1

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: 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: []