Write business logic for Ruby/Rails that scales.
- Supported Ruby and Rails
- Introduction
- Installation
- The Mental Model
- The Basic Structure
- Further Reading
- Development
- Contributing
- License
- Code of Conduct
This library is tested (100% coverage) against:
| Ruby / Rails | 6.0 | 6.1 | 7.0 | 7.1 | Edge |
|---|---|---|---|---|---|
| 2.7 | ✅ | ✅ | ✅ | ✅ | |
| 3.0 | ✅ | ✅ | ✅ | ✅ | |
| 3.1 | ✅ | ✅ | ✅ | ✅ | ✅ |
| 3.2 | ✅ | ✅ | ✅ | ✅ | ✅ |
| 3.3 | ✅ | ✅ | ✅ | ✅ | ✅ |
| Head | ✅ | ✅ |
solid-process is a Ruby/Rails library designed to encapsulate business logic into manageable processes. It simplifies writing, testing, maintaining, and evolving your code, ensuring it remains clear and approachable as your application scales.
Key Objectives:
-
Seamless Rails integration: Designed to complement Ruby on Rails, this library integrates smoothly without conflicting with existing framework conventions and features.
-
Support progressive mastery: Offers an intuitive entry point for novices while providing robust, advanced features that cater to experienced developers.
-
Promote conceptual integrity and rapid onboarding: By maintaining a consistent design philosophy,
solid-processreduces the learning curve for new developers, allowing them to contribute more effectively and quickly to a codebase. -
Enhanced observability: Equipped with sophisticated instrumentation mechanisms, the library enables detailed logging and tracing without compromising code readability, even when processes are nested.
Take a look at the examples folder in this repository. Or check out Solid Rails App for a complete example of how to use solid-process in a Rails application. Twelve versions (branches) show how the gem can be incrementally integrated. Access it to see from simple services/form objects to implementing the ports and adapters (hexagonal) architectural pattern.
Install the gem and add to the application's Gemfile by executing:
$ bundle add solid-process
If bundler is not being used to manage dependencies, install the gem by executing:
$ gem install solid-process
And require it in your code:
require 'solid/process'
A sequence of steps or actions to achieve a specific end. In other words, it is a series of steps that produce a result.
It is a class that encapsulates reusable business logic. Its main goal is to act as an orchestrator who knows the order, what to use, and the steps necessary to produce an expected result.
The business rule is directly coupled with business needs. We are often unclear about these rules and how they will be implemented as code. Clarity tends to improve over time and after many maintenance cycles.
For this reason, this abstraction embraces emerging design, allowing developers to implement code in a basic structure that can evolve and become sophisticated through the learnings obtained over time.
- Make it Work, then
- Make it Better, then
- Make it Even Better.
Using the emerging design concept, I invite you to embrace this development cycle, write the minimum necessary to implement processes and add more solid-process features based on actual needs.
All Solid::Process requires at least two things: an input and a call method.
- The
inputis a set of attributes needed to perform the work. - The
#callmethod is the entry point and where the work is done.
- It receives the attributes Hash (symbolized keys), defined by the
input. - It returns a
SuccessorFailureas the output.
class User::Creation < Solid::Process
input do
# Define the attributes needed to perform the work
end
def call(attributes)
# Perform the work and return a Success or Failure as the output
end
endclass User::Creation < Solid::Process
input do
attribute :email
attribute :password
attribute :password_confirmation
end
def call(attributes)
user = User.create(attributes)
if user.persisted?
Success(:user_created, user: user)
else
Failure(:user_not_created, user: user)
end
end
endTo call a process, you can use the call method directly, or instantiate the class and call the #call method.
###############
# Direct call #
###############
User::Creation.call(email: '[email protected]', password: 'password', password_confirmation: 'password')
# => #<Solid::Output::Success type=:user_created value={:user=>#<User id: 1, ...>}>
########################
# Instantiate and call #
########################
process = User::Creation.new
process.call(email: '[email protected]', password: 'password', password_confirmation: 'password')For now, it's essential to know that a process instance is stateful, and because of this, you can call it only once.
process = User::Creation.new
input = {email: '[email protected]', password: 'password', password_confirmation: 'password'}
process.call(input)
process.call(input)
# The `User::Creation#output` is already set. Use `.output` to access the result or create a new instance to call again. (Solid::Process::Error)- 01 - Basic Usage
- 02 - Intermediate Usage
- 03 - Advanced Usage
- 04 - Error Handling
- 05 - Testing
- 06 - Instrumentation / Observability
- 07 - Rails Integration
- 08 - Internal libraries
- Solid::Input
- Solid::Model
- Solid::Value
- ActiveModel validations
- 09 - Ports and Adapters (Hexagonal Architecture)
After checking out the repo, run bin/setup to install dependencies. Then, run bundle exec rake dev to run the tests. You can also run bin/console for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run bundle exec rake install. To release a new version, update the version number in version.rb, and then run bundle exec rake release, which will create a git tag for the version, push git commits and the created tag, and push the .gem file to rubygems.org.
Bug reports and pull requests are welcome on GitHub at https://github.com/solid-process/solid-process. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the code of conduct.
The gem is available as open source under the terms of the MIT License.
Everyone interacting in the Solid::Process project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.