README.md in rails-patterns-0.1.1 vs README.md in rails-patterns-0.2.0
- old
+ new
@@ -69,5 +69,54 @@
class User < ApplicationRecord
scope :recenty_activated, RecentlyActivatedUsersQuery
end
```
+
+## Service
+
+### When to use it
+
+Service objects are commonly used to mitigate problems with model callbacks that interact with external classes ([read more...](http://samuelmullen.com/2013/05/the-problem-with-rails-callbacks/)).
+Service objects are also useful for handling processes involving multiple steps. E.g. a controller that performs more than one operation on its subject (usually a model instance) is a possible candidate for Extract ServiceObject (or Extract FormObject) refactoring.
+
+### Assumptions and rules
+
+* Service objects are always used by calling class-level `.call` method
+* Service objects have to implement `#call` method
+* Calling service object's `.call` method executes `#call` and returns service object instance
+* A result of `#call` method is accessible through `#result` method
+* It is recommended for `#call` method to be the only public method of service object (besides state readers)
+* It is recommended to name service object classes after commands (e.g. `ActivateUser` instead of `UserActivation`)
+
+### Examples
+
+#### Declaration
+
+```ruby
+class ActivateUser < Patterns::Service
+ def initialize(user)
+ @user = user
+ end
+
+ def call
+ user.activate!
+ NotificationsMailer.user_activation_notification(user).deliver_now
+ user
+ end
+
+ private
+
+ attr_reader :user
+end
+```
+
+#### Usage
+
+```ruby
+ user_activation = ActivateUser.call(user)
+ user_activation.result # <User id: 5803143, email: "tony@patterns.dev ...
+```
+
+## Further reading
+
+* [7 ways to decompose fat active record models](http://blog.codeclimate.com/blog/2012/10/17/7-ways-to-decompose-fat-activerecord-models/)