Skip to content

Commit fbb9082

Browse files
Bold key statements and soften conclusion wording
1 parent 9a201ee commit fbb9082

1 file changed

Lines changed: 9 additions & 9 deletions

File tree

posts/2026-03-31-rails-apps-have-layers-but-no-modules.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,15 @@ publish: false
77

88
# Rails apps have layers but no modules
99

10-
You can have 200 models and zero modules. That's the problem with typical Rails conventions. Rails supports layers - models, views, controllers. But layers are not modules. Within one layer - especially models - usually all is mixed together. There are no boundaries.
10+
You can have 200 models and zero modules. That's the problem with typical Rails conventions. Rails supports layers - models, views, controllers. **But layers are not modules.** Within one layer - especially models - usually all is mixed together. There are no boundaries.
1111

1212
<!-- more -->
1313

1414
```ruby
1515
Order.first.user.invoices.last.line_items
1616
```
1717

18-
Such code is not so uncommon. It crosses 4 business boundaries. In just 1 line of code. All thanks to associations.
18+
Such code is not so uncommon. It crosses **4 business boundaries**. In just 1 line of code. All thanks to associations.
1919

2020
## The problem with associations
2121

@@ -60,13 +60,13 @@ Order.first.user.invoices.last.line_items
6060
This is how we boil the frog. One step at a time. One column at a time. One association at a time.
6161

6262
The result?
63-
A User class with 100 columns in the database.
63+
A User class with **100 columns** in the database.
6464

6565
## DRY and god models
6666

6767
There is a misconception about DRY - Don't Repeat Yourself. We have an existing User class. It feels right to just add things there.
6868

69-
No one was ever fired for adding a new column to the users table.
69+
**No one was ever fired for adding a new column to the users table.**
7070

7171
It feels like the User class is the right abstraction for DRY. Yet, it always ends as the god model.
7272

@@ -83,28 +83,28 @@ They also are a good solution to the transaction boundary.
8383

8484
Service objects are a new layer. We could now call it MVCS. Model View Controller Service. It's not bad. It does help with unit testing - it's easier to unit test a service object than a controller action.
8585

86-
Service objects do nothing about modularisation.
86+
**Service objects do nothing about modularisation.**
8787

8888
They don't create new boundaries. They don't help with composing modules.
8989

90-
Service objects are just another horizontal slice.
90+
Service objects are just **another horizontal slice**.
9191

9292
## Microservices
9393

9494
It's usually around this phase in the architecture - MVCS - when a decision is made.
9595

9696
We will go microservices.
9797

98-
Sometimes it comes from the team itself - what can be a stronger boundary than a network? The team hopes it will enforce a better design. Microservices bring the hope of starting fresh — new language, new design, better boundaries. But the boundaries still aren't modules.
98+
Sometimes it comes from the team itself - what can be a stronger boundary than a network? The team hopes it will enforce a better design. Microservices bring the hope of starting fresh — new language, new design, better boundaries. But the boundaries **still aren't modules**.
9999

100100
Are microservices helping with the modularisation?
101101
Nope. They are just yet another horizontal layer. This time we add a layer behind a network call. We no longer have transactions, it's harder to run tests, the build takes longer. All for the benefit for having 3 new Go microservices and adding new layers of serialisation/deserialisation.
102102

103-
More layers, less performance, but still no modules.
103+
**More layers, less performance, but still no modules.**
104104

105105
## A bitter conclusion
106106

107-
Rails makes it easy to add code. It makes it impossible to isolate it.
107+
Rails makes it easy to add code. It doesn't make it easy to **isolate it**.
108108

109109
200 models. Five layers. Zero modules. That's the default.
110110

0 commit comments

Comments
 (0)