-
Notifications
You must be signed in to change notification settings - Fork 42
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Earlier Draft: Service objects #6
base: presenters
Are you sure you want to change the base?
Conversation
* Display if minor on profile page. * Add creation of minor to sample_data.rake
* Too much logic in controller method create. * No tests added as not very convenient for a complicated controller method! * Subtle bug in this commit
* Handles checking profanity for minors, and adds profanity_count on users table. * Sample data creates user '[email protected]' who is a minor. * Added tests on service object.
* Clarified and simplified tests. * Left in 2 broken tests regarding the profanity counter.
* All tests now pass * However, if you try this with a minor: * You get the correct error message. * BUT, the profanity is posted!
* Also added test confirming post created for non-profanity.
* Don't use @user.microposts.build(content: @content) because we will save the user when there's profanity. * Instead, call Micropost.new * Fixes broken test
* Example of using the ProfanityChecker service in multiple places.
This service is too much coupled with the knowledge of a Rails controller (eg. I'd like to share some nice to have things:
|
Service Object is not a variation of a Presenter technique. They are two different things. Presenter helps out with the presentation layer, while Service layer acts as an intermediary between multiple models (and doesn't care about presentation per se). This article from Martin Fowler should shine some more light on the Service layer. I agree with @jodosha that the pattern you are presenting is too coupled to the controller. Perhaps rename it to "Response Object", because I think there is something interesting here, but I would not confuse it with Service Objects. |
Service Objects
This code demonstrates moving complex controller code into a class that manages model interactions, aka a
Service Object
. The controller calls the Service Object and it returns an object that encapsulates what the controller should do. This includes flashmessages, redirects, etc. The example class
ControllerResponse
provides asample of how to do this. A service object could create a presenter for the
controller to pass to the view.
After getting this reviewed, I've developed an alternative approach that focuses on keeping controller parts (setting flash, etc.) in the controller and moves other logic into the model code. See #12.
Service Objects Applicable Situation
Service Objects Example for Micro Blog
This code is not easily testable, being on the controller. The addition of the
profanity_words
method on the controller also does not fit. I don't go intobuilding tests, as the refactor will allow easy testing.
MicropostCreationService
is simple:ControllerResponse
class so as not bethrowing exceptions for error scenarios.
the code should print all the profanity in the message, and add the number of
profanity words to the user's profanity counter.
size of classes and clarifies the tests. The main advantage of having the
ProfanityChecker
into its own class is that the Micropost can also use thelogic for validation.
the usefulness of having concise and simple unit tests on the
MicropostCreationService
.Service Object Solution
services
directory (or optionally in models).controller.
spec/services
directory.Service Object Advantages
class are around a single purpose.
Service Object Disadvantages
or decorator, or maybe a method class called by the model.