Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/guideline-tech/subroutine
Subroutine makes it easy to write encapsulated, feature-driven code. It handles the boilerplate of inputs, outputs, type casting, and validation and lets you focus on the important functional code.
https://github.com/guideline-tech/subroutine
encapsulation form-objects ruby service-objects
Last synced: 3 months ago
JSON representation
Subroutine makes it easy to write encapsulated, feature-driven code. It handles the boilerplate of inputs, outputs, type casting, and validation and lets you focus on the important functional code.
- Host: GitHub
- URL: https://github.com/guideline-tech/subroutine
- Owner: guideline-tech
- License: mit
- Created: 2015-02-28T22:20:28.000Z (over 9 years ago)
- Default Branch: main
- Last Pushed: 2024-04-07T15:13:48.000Z (7 months ago)
- Last Synced: 2024-04-07T17:51:14.802Z (7 months ago)
- Topics: encapsulation, form-objects, ruby, service-objects
- Language: Ruby
- Homepage:
- Size: 209 KB
- Stars: 40
- Watchers: 9
- Forks: 13
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.MD
- License: LICENSE.txt
- Codeowners: .github/CODEOWNERS
Awesome Lists containing this project
README
# Subroutine
A gem that provides an interface for creating feature-driven operations. You've probably heard at least one of these terms: "service objects", "form objects", "intentions", or "commands". Subroutine calls these "ops" and really it's just about enabling clear, concise, testable, and meaningful code.
## Example
So you need to sign up a user? or maybe update one's account? or change a password? or maybe you need to sign up a business along with a user, associate them, send an email, and queue a worker in a single request? Not a problem, create an op for any of these use cases. Here's the signup example.
```ruby
class SignupOp < ::Subroutine::Opstring :name
string :email
string :passwordstring :company_name
validates :name, presence: true
validates :email, presence: true
validates :password, presence: true
validates :company_name, presence: trueoutputs :user
outputs :business, type: Business # validate that output type is an instance of Businessprotected
def perform
u = create_user!
b = create_business!(u)deliver_welcome_email(u)
output :user, u
output :business, b
enddef create_user!
User.create!(name: name, email: email, password: password)
enddef create_business!(owner)
Business.create!(company_name: company_name, owner: owner)
enddef deliver_welcome_email(u)
UserMailer.welcome(u.id).deliver_later
end
end
```## So why use this?
- Avoid cluttering models or controllers with logic only applicable to one intention. You also don't need strong parameters because the inputs to the Op are well-defined.
- Test the Op in isolation
- Clear and concise intention in a single file
- Multi-model operations become simple## Continue Reading
- [Implementing an Op](https://github.com/guideline-tech/subroutine/wiki/Implementing-an-Op)
- [Using an Op](https://github.com/guideline-tech/subroutine/wiki/Using-an-Op)
- [Errors](https://github.com/guideline-tech/subroutine/wiki/Errors)
- [Basic Usage in Rails](https://github.com/guideline-tech/subroutine/wiki/Rails-Usage)## Development
Run the test suite against current Rails version:
```
bundle exec rake test
```Run the test suite against all supported Rails versions using `appraisal`:
```
bundle exec appraisal rake test
```For help updating the `Gemfile` or changing supported Rails versions, see the `appraisal` gem [README](https://github.com/thoughtbot/appraisal#usage).
Note that the gemfiles in `gemfiles/*` are auto-generated by `appraisal` and should not be modified directly.