Skip to content

Commit 66bebc0

Browse files
committed
Update README.md
1 parent eebb5ee commit 66bebc0

11 files changed

+129
-53
lines changed

README.md

Lines changed: 51 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,18 @@
1111

1212
## 📚 Table of Contents <!-- omit from toc -->
1313

14-
- [Supported Ruby and Rails](#supported-ruby-and-rails)
1514
- [Introduction](#introduction)
1615
- [Installation](#installation)
17-
- [The Mental Model](#the-mental-model)
1816
- [The Basic Structure](#the-basic-structure)
19-
- [Calling a Process](#calling-a-process)
2017
- [Further Reading](#further-reading)
2118
- [Development](#development)
2219
- [Contributing](#contributing)
2320
- [License](#license)
2421
- [Code of Conduct](#code-of-conduct)
22+
- [Acknowledgments](#acknowledgments)
23+
- [About](#about)
2524

26-
## Supported Ruby and Rails
25+
## Supported Ruby and Rails <!-- omit from toc -->
2726

2827
This library is tested (100% coverage) against:
2928

@@ -40,63 +39,55 @@ This library is tested (100% coverage) against:
4039

4140
`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.
4241

43-
**Key Objectives:**
42+
**Features:** (Touch to expand)
4443

45-
1. **Seamless Rails integration:** Designed to complement Ruby on Rails, this library integrates smoothly without conflicting with existing framework conventions and features.
44+
<details><summary>1️⃣ <strong>Seamless Rails integration</strong></summary>
4645

47-
2. **Support progressive mastery:** Offers an intuitive entry point for novices while providing robust, advanced features that cater to experienced developers.
46+
> Designed to complement Ruby on Rails, this library integrates smoothly without conflicting with existing framework conventions and features.
4847
49-
3. **Promote conceptual integrity and rapid onboarding:** By maintaining a consistent design philosophy, `solid-process` reduces the learning curve for new developers, allowing them to contribute more effectively and quickly to a codebase.
48+
</details>
5049

51-
4. **Enhanced observability:** Equipped with sophisticated instrumentation mechanisms, the library enables detailed logging and tracing without compromising code readability, even when processes are nested.
50+
<details><summary>2️⃣ <strong>Support progressive mastery</strong></summary>
5251

53-
<p align="right"><a href="#-table-of-contents-">⬆️ &nbsp;back to top</a></p>
52+
> Offers an intuitive entry point for novices while providing robust, advanced features that cater to experienced developers.
5453
55-
### Examples <!-- omit in toc -->
54+
</details>
5655

57-
Take a look at the [examples](examples) folder in this repository. Or check out [Solid Rails App](https://github.com/solid-process/solid-rails-app) for a complete example of how to use `solid-process` in a Rails application. [Twelve versions (branches)](https://github.com/solid-process/solid-rails-app?tab=readme-ov-file#-repository-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.
56+
<details><summary>3️⃣ <strong>Promote conceptual integrity and rapid onboarding</strong></summary>
5857

59-
<p align="right"><a href="#-table-of-contents-">⬆️ &nbsp;back to top</a></p>
58+
> By maintaining a consistent design philosophy, `solid-process` reduces the learning curve for new developers, allowing them to contribute more effectively and quickly to a codebase.
6059
61-
## Installation
60+
</details>
6261

63-
Install the gem and add to the application's Gemfile by executing:
62+
<details><summary>4️⃣ <strong>Enhanced observability</strong></summary>
6463

65-
$ bundle add solid-process
64+
> Equipped with sophisticated instrumentation mechanisms, the library enables detailed logging and tracing without compromising code readability, even when processes are nested.
6665
67-
If bundler is not being used to manage dependencies, install the gem by executing:
68-
69-
$ gem install solid-process
70-
71-
And require it in your code:
72-
73-
require 'solid/process'
66+
</details>
7467

7568
<p align="right"><a href="#-table-of-contents-">⬆️ &nbsp;back to top</a></p>
7669

77-
## The Mental Model
70+
### Examples <!-- omit in toc -->
7871

79-
### What is a process? <!-- omit from toc -->
72+
Check out [Solid Rails App](https://github.com/solid-process/solid-rails-app) for a complete example of how to use `solid-process` in a Rails application. [Twelve versions (branches)](https://github.com/solid-process/solid-rails-app?tab=readme-ov-file#-repository-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.
8073

81-
A sequence of steps or actions to achieve a specific end. In other words, it is a series of steps that produce a result.
74+
You can also check the [examples](examples) directory for more simple examples of how to use the gem.
8275

83-
### What is a `Solid::Process`? <!-- omit from toc -->
76+
<p align="right"><a href="#-table-of-contents-">⬆️ &nbsp;back to top</a></p>
8477

85-
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.
78+
## Installation
8679

87-
### Emergent Design <!-- omit from toc -->
80+
Install the gem and add to the application's Gemfile by executing:
8881

89-
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.
82+
$ bundle add solid-process
9083

91-
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.
84+
If bundler is not being used to manage dependencies, install the gem by executing:
9285

93-
### The Mantra <!-- omit from toc -->
86+
$ gem install solid-process
9487

95-
* **Make it Work**, then
96-
* **Make it Better**, then
97-
* **Make it Even Better**.
88+
And require it in your code:
9889

99-
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.
90+
require 'solid/process'
10091

10192
<p align="right"><a href="#-table-of-contents-">⬆️ &nbsp;back to top</a></p>
10293

@@ -145,7 +136,7 @@ end
145136

146137
<p align="right"><a href="#-table-of-contents-">⬆️ &nbsp;back to top</a></p>
147138

148-
### Calling a Process
139+
### Calling a Process <!-- omit from toc -->
149140

150141
To call a process, you can use the `call` method directly, or instantiate the class and call the `#call` method.
151142

@@ -183,19 +174,20 @@ process.call(input)
183174

184175
## Further Reading
185176

186-
- [01 - Basic Usage](docs/01_BASIC_USAGE.md)
187-
- [02 - Intermediate Usage](docs/02_INTERMEDIATE_USAGE.md)
188-
- [03 - Advanced Usage](docs/03_ADVANCED_USAGE.md)
189-
- [04 - Error Handling](docs/04_ERROR_HANDLING.md)
190-
- [05 - Testing](docs/05_TESTING.md)
191-
- [06 - Instrumentation / Observability](docs/06_INSTRUMENTATION.md)
192-
- [07 - Rails Integration](docs/07_RAILS_INTEGRATION.md)
193-
- [08 - Internal libraries](docs/08_INTERNAL_LIBRARIES.md)
177+
1. [Key Concepts](docs/010_KEY_CONCEPTS.md)
178+
2. [Basic Usage](docs/020_BASIC_USAGE.md)
179+
3. [Intermediate Usage](docs/030_INTERMEDIATE_USAGE.md)
180+
4. [Advanced Usage](docs/040_ADVANCED_USAGE.md)
181+
5. [Error Handling](docs/050_ERROR_HANDLING.md)
182+
6. [Testing](docs/060_TESTING.md)
183+
7. [Instrumentation / Observability](docs/070_INSTRUMENTATION.md)
184+
8. [Rails Integration](docs/080_RAILS_INTEGRATION.md)
185+
9. [Internal libraries](docs/090_INTERNAL_LIBRARIES.md)
194186
- Solid::Input
195187
- Solid::Model
196188
- Solid::Value
197189
- ActiveModel validations
198-
- [09 - Ports and Adapters (Hexagonal Architecture)](docs/09_PORTS_AND_ADAPTERS.md)
190+
10. [Ports and Adapters (Hexagonal Architecture)](docs/100_PORTS_AND_ADAPTERS.md)
199191

200192
<p align="right"><a href="#-table-of-contents-">⬆️ &nbsp;back to top</a></p>
201193

@@ -224,3 +216,16 @@ The gem is available as open source under the terms of the [MIT License](https:/
224216
Everyone interacting in the Solid::Process project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/solid-process/solid-process/blob/main/CODE_OF_CONDUCT.md).
225217

226218
<p align="right"><a href="#-table-of-contents-">⬆️ &nbsp;back to top</a></p>
219+
220+
## Acknowledgments
221+
222+
I want to thank some people who helped me by testing and giving feedback as this project took shape, they are:
223+
224+
- [Diego Linhares](https://github.com/diegolinhares) and [Ralf Schmitz Bongiolo](https://github.com/mrbongiolo) they were the brave ones who worked for a few months with the first versions of the ecosystem (it was called B/CDD). Their feedback was essential for improving DX and helped me to pivot some core decisions.
225+
- [Vitor Avelino](https://github.com/vitoravelino), [Tomás Coêlho](https://github.com/tomascco), [Haroldo Furtado](https://github.com/haroldofurtado) (I could repeat Ralf and Diego again) for the various feedbacks, documentation, API, support and words of encouragement.
226+
227+
## About
228+
229+
[Rodrigo Serradura](https://rodrigoserradura.com) created this project. He is the Solid Process creator and has already made similar gems like the [u-case](https://github.com/serradura/u-case) and [kind](https://github.com/serradura/kind). This gem can be used independently, but it also contains essential features that facilitate the adoption of Solid Process (the method) in code.
230+
231+
<p align="right"><a href="#-table-of-contents-">⬆️ &nbsp;back to top</a></p>

docs/010_KEY_CONCEPTS.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<small>
2+
3+
`Previous` [Table of Contents](../README.md#further-reading) | `Next` [Basic Usage](./020_BASIC_USAGE.md)
4+
5+
</small>
6+
7+
# The Key Concepts
8+
9+
### What is a process?
10+
11+
A sequence of steps or actions to achieve a specific end. In other words, it is a series of steps that produce a result.
12+
13+
### What is a `Solid::Process`?
14+
15+
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.
16+
17+
### Emergent Design
18+
19+
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.
20+
21+
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.
22+
23+
### The Mantra
24+
25+
* **Make it Work**, then
26+
* **Make it Better**, then
27+
* **Make it Even Better**.
28+
29+
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.
30+
31+
<p align="right"><a href="#the-key-concepts">⬆️ &nbsp;back to top</a></p>
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
<small>
2+
3+
`Previous` [Key Concepts](./010_KEY_CONCEPTS.md) | `Next` [Intermediate Usage](./030_INTERMEDIATE_USAGE.md)
4+
5+
</small>
6+
17
# Basic Usage
28

39
**Status:** 🟡 `in-progress`
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
<small>
2+
3+
`Previous` [Basic Usage](./020_BASIC_USAGE.md) | `Next` [Advanced Usage](./040_ADVANCED_USAGE.md)
4+
5+
</small>
6+
17
# Intermediate Usage
28

39
**Status:** 🟡 `in-progress`
Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
<small>
2+
3+
`Previous` [Intermediate Usage](./030_INTERMEDIATE_USAGE.md) | `Next` [Error Handling](./050_ERROR_HANDLING.md)
4+
5+
</small>
6+
17
# Advanced Usage
28

39
**Status:** 🟡 `in-progress`
@@ -6,15 +12,31 @@ In this section, we will learn how to use input normalization and validation, de
612

713
```ruby
814
class User::Registration < Solid::Process
15+
deps do
16+
attribute :mailer, default: UserMailer
17+
attribute :token_creation, default: User::Token::Creation
18+
attribute :task_list_creation, default: Account::Task::List::Creation
19+
end
20+
921
input do
1022
attribute :email, :string
1123
attribute :password, :string
1224
attribute :password_confirmation, :string
25+
26+
before_validation do
27+
self.email = email.downcase.strip
28+
end
29+
30+
with_options presence: true do
31+
validates :email, format: User::Email::REGEXP
32+
validates :password, confirmation: true, length: {minimum: User::Password::MINIMUM_LENGTH}
33+
end
1334
end
1435

1536
def call(attributes)
1637
rollback_on_failure {
1738
Given(attributes)
39+
.and_then(:check_if_email_is_taken)
1840
.and_then(:create_user)
1941
.and_then(:create_user_account)
2042
.and_then(:create_user_inbox)
@@ -26,6 +48,12 @@ class User::Registration < Solid::Process
2648

2749
private
2850

51+
def check_if_email_is_taken(email:, **)
52+
input.errors.add(:email, "has already been taken") if User.exists?(email:)
53+
54+
input.errors.any? ? Failure(:invalid_input, input:) : Continue()
55+
end
56+
2957
def create_user(email:, password:, password_confirmation:, **)
3058
user = User.create(email:, password:, password_confirmation:)
3159

@@ -45,19 +73,19 @@ class User::Registration < Solid::Process
4573
end
4674

4775
def create_user_inbox(account:, **)
48-
account.task_lists.inbox.create!
49-
50-
Continue()
76+
case deps.task_list_creation.call(account:, inbox: true)
77+
in Solid::Success(task_list:) then Continue()
78+
end
5179
end
5280

5381
def create_user_token(user:, **)
54-
user.create_token!
55-
56-
Continue()
82+
case deps.token_creation.call(user:)
83+
in Solid::Success(token:) then Continue()
84+
end
5785
end
5886

5987
def send_email_confirmation(user:, **)
60-
UserMailer.with(
88+
deps.mailer.with(
6189
user:,
6290
token: user.generate_token_for(:email_confirmation)
6391
).email_confirmation.deliver_later
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)