My first dive into DDD concepts in Ruby
For someone who is experiencing Rails fatigue, it would be worth looking into alternatives for developing architectures with Ruby. It does not mean that it would require abandoning Rails at all because there are solutions that allow developing DDD concepts with the most popular Ruby framework. I will leave a discussion about whether you need this architecture approach in your app or not and only focus on how to start with DDD if you are not familiar with it.
Based on my research, it looks like there are two possible ways to go with DDD in Ruby. The first one is Eventide with code examples available here: https://github.com/eventide-examples
These are pure Ruby examples. There is also the Eventide Rails project. However, not much is going there:
The second one is the Rails Event Store with a demo app: https://github.com/RailsEventStore/cqrs-es-sample-with-res
It is integration with Rails, and a demo is also available on Heroku, which makes it very easy to play with it.
After having a look into Eventide examples and the CQRS project, what is similar between them is the concept of Commands and Events. For someone familiar with Rails who want to get hands dirty with Domain-Driven Design, I believe that the great place to start is cqrs-es-sample-with-res repo from Rails Event Store. So let’s have a look.
Rails Event Store
As you probably know from the previous section, the gem that brings all the necessary things to start the journey with Domain-Driven Design and Rails is called Rails Event Store.
The demo repo is actively maintained, consists of a use case of an e-commerce store with the implementation of around ten events that model business operations. For those who want to learn more, there are also Docs available here: https://railseventstore.org/
I decided to run a demo project locally, generate some events, and then connect database GUI client to see how Events have been stored in the database and what’s going on with other data like typical Rails models. Later on, to fully understand how things work, I added my custom Event.
Adding custom event
Step 1. Trigger command in Rails controller.
This part is easy. So here is where all the journey starts. I decided to add a tracking event when the user visits the Order page, so I need to call the following code in OrdersController#show action:
The integration of this code with a controller requires changes in two other places. We need to register our command:
To finalize this part, the configuration for our command bus is needed:
Step 2. Command Handler.
The next step is to handle our Command in the following file:
The code above calls the Order#visit instance method, which implements the following code:
Step 3. The last part, Event.
And here is the moment where I got stuck for a moment. I got the following error:
Missing handler method apply_order_visited on aggregate Ordering::Order
Let’s fix it by adding the following code in the same file:
The last part is to handle our Event. To do this, we need to update our code in a few places. Add an Event:
Add subscription in config:
And the final part where the actual business logic happens is our read model. This read model is placed all together with other models like order or order_line (ActiveRecord):
Because there is no Demo app for the Eventide project that shows how to integrate it with Rails, I decided to go with RES to learn more about DDD. For someone already familiar with DDD concepts, it would be good to give Eventide repo a shoot. Check this blog post for more info: https://blog.arkency.com/my-first-10-minutes-with-eventide/