Domain Driven Design

Summarized using AI

Trailblazer: A new Architecture for Rails

Nick Sutterer and J Austin Hughey • May 07, 2015 • Atlanta, GA

The video titled "Trailblazer: A New Architecture for Rails" presented by Nick Sutterer and J Austin Hughey at RailsConf 2015 discusses the prominent issues of structuring complex applications in Rails and introduces Trailblazer as a solution.

The main points addressed in the talk include:

- Challenges with Active Record: The speakers raise a specific issue regarding Active Record and the unwanted automatic persistence of object states, which illustrates common pain points in Rails development.

- Monolithic Architecture Concerns: While Rails simplifies the initial stages of web development through its model-view-controller (MVC) approach, applications tend to become complex as they scale, leading developers to struggle with code organization.

- Cluttered Controllers and Models: The talk outlines how business logic often gets intertwined with controller and model responsibilities, resulting in tangled code that is difficult to maintain.

- Introducing Operations and Abstraction Layers: Trailblazer addresses these issues by introducing operations that encapsulate business logic, clearly defining areas for various tasks and improving the separation between model domains and application logic.

- Controller Simplification: In a Trailblazer setup, controllers serve primarily as dispatchers, radically reducing their responsibilities and keeping them clean.

- Flexibility of Abstraction: The speakers highlight that by using Trailblazer, developers can create multiple layers of abstraction tailored to their application's needs, enhancing organization without sacrificing the familiar Rails structure.

- Live Demonstration: J Austin Hughey demonstrates a blog application built with Trailblazer, showcasing how to implement various functionalities while keeping controllers lightweight and focused on routing.

In conclusion, the speakers advocate for adopting Trailblazer as a framework to facilitate better structuring of Rails applications. They emphasize that using clear operations and defined layers will lead to applications that are more manageable, maintainable, and resilient to change, urging the audience to explore Trailblazer further for enhanced code quality and development efficiency.

Trailblazer: A new Architecture for Rails
Nick Sutterer and J Austin Hughey • May 07, 2015 • Atlanta, GA

by Nick Sutterer and J Austin Hughey

Trailblazer introduces several new abstraction layers into Rails. It gives developers structure and architectural guidance and finally answers the question of "Where do I put this kind of code?" in Rails. This talk walks you through a realistic development of a Rails application with Trailblazer and discusses every bloody aspect of it.

RailsConf 2015

00:00:12.320 Hi guys, thank you very much! First of all, I have to clarify that the talk title in the program is wrong. The talk is called 'Trailblazer: A New Architecture for Rails' and not 'See You on the Trail' because I'm not going to talk about hiking. I have no idea how this title got into the RailsConf program, but anyway, you're here and that's great. Thank you! I'll get you started.
00:00:38.370 Before we start the actual talk, I have a serious question. I have a problem with Active Record: I have this Post class and a Comment model that has a 'has many' relationship. A post can have a lot of comments, and my problem is that when I create a post, the post becomes persistent. Then, when I add comments to that post, how do I prevent Active Record from automatically saving the new state of this post? Because I don't want the comments to be persisted yet. I have tried several approaches, but Active Record saves the comments each time. Can anyone here explain how I can prevent Active Record from saving the comments until I call save? It seems like the build method calls new internally. This is a serious question because we encounter this issue in Reform when we set up collections and assign them to the collection attribute, like comments. It ends up saving the entire object, and I don't want that. If anyone has an idea, please hit me up after the talk because I'm desperate and don't want to sift through all the Active Record documentation.
00:02:19.340 Okay, let's talk about Trailblazer. Before I came to Atlanta, I traveled a little bit to conferences. My last stop was in Venice, but actually, I was in Minsk, Belarus. It was a great conference with fantastic speakers and a couple of drinks. I got confused with the slides, sorry. Before that, I was in Venice, Lithuania, at the Rubicon, which was also an awesome conference with great speakers and drinks. Before that, I was in Poland at the Bross conference in Rostov. Rostov is a beautiful city with churches and cathedrals. I have no idea what the difference is, but it's a lovely place. Then I went to Brazil for the Tropical Ruby Conference, which was amazing! Has anyone been to Brazil yet? Tropical RubyConf was fantastic with great speakers and drinks.
00:03:39.799 Before that, I was in Mexico in Oaxaca—what a great place! I gave a talk at a user group about Trailblazer, and the community there is incredibly cool. We had some good speeches, a few drinks, and I even learned how to dance cumbia, which was awesome! I live in Australia now, but I’m originally from Germany—hence the accent. I'm not going to show you photos of Australia because it’s beautiful, and you all should come visit me there. Now, let’s talk about Rails.
00:04:12.470 We’re all working with Rails, right? Yes, this is RailsConf! Rails is a famous web framework, well-known for its monolithic architecture. This is a monolith, and this is a service-oriented architecture. Rails provides a simple setup with three abstraction layers: the model, the controller, and the view. This is awesome because it allows you to get applications up and running in minutes. You can build a basic application in 15 minutes or even faster!
00:05:15.910 The downside is that you only have these three abstraction layers, and as a result, a lot of your code ends up in the views, the controllers, and the models. This can lead to messy and complex applications when they grow in size. Initially, Rails promised conventions and standards, but as the application complexity increases, developers often find themselves asking, 'Where do I put this kind of code in Rails?' We end up with huge models and thin controllers, often leading to deep levels of nesting and unmanageable structure that complicates code reuse.
00:06:10.690 For me, the monolithic architecture is not sufficient. It’s fine to maintain a single application without having to deploy multiple applications to solve a single problem. Some might say the only alternative to a monolithic architecture is microservices, but that’s not true. A monolith can incorporate service-oriented architecture, and one can organize services inside a monolith. When I mention monoliths, I refer to a Rails setup that is well-structured. So please don't conflate the concepts of monoliths and microservices when we talk about these architectures.
00:07:30.279 However, in the Rails community, adding new abstraction layers to MVC often leads to others accusing you of over-engineering or adhering to an enterprise-level solution. There are complaints that adding too many objects slows down the application since everything is an object in Ruby. My experience leads me to believe that it's unfair to characterize Rails development as straightforward. It can be easy to begin, but when it comes to structuring complex applications, it often becomes convoluted and difficult.
00:08:20.130 After ten years of working with Rails applications, I can tell you the common issues boil down to cluttered controllers and models. You end up implementing logic, handling different contexts, adding callbacks, and rendering logic all within the controllers. These practices load the controller with a significant amount of unnecessary complexity, with multiple levels of nested conditions and business logic. The result is that many Rails applications become hard to maintain and understand.
00:09:27.660 To simplify this, we need clear structure and layering. In a typical Rails application, we handle everything from request dispatching to the business logic within various parts, which often leads to overlapping responsibilities. Controller actions take on too many responsibilities, including persistence and validation, while models become overloaded with business logic.
00:10:09.580 The main point I want to make about Trailblazer is to help provide that clearer structure and abstraction within your Rails applications. In this approach, we can create a clear distinction between the layers of our applications and their responsibilities, allowing us to adhere to better practices and making our applications easier to manage.
00:10:30.220 Trailblazer introduces operations as a way to encapsulate business logic in frameworks, creating clearly defined areas for various tasks. Each operation can manage its own set of validations, business logic, and callbacks, thus maintaining a clean separation between the model domain and the application logic.
00:11:12.130 Now we can also introduce new abstractions in Trailblazer beyond the typical Rails structures, making it easier to manage our code and align it with our domain-driven designs. The benefit of this structure is that it breaks down our application into manageable components without losing touch with the overall organization of our code.
00:12:57.410 To illustrate how operations work and where encapsulation happens in Trailblazer, each operation can inherit properties and contracts, streamlining the organization. You can maintain multiple models and their associations while keeping an eye on the business logic. Furthermore, operations in Trailblazer are not just about CRUD—they can facilitate interactions with nested attributes, managing the complexity without convoluting the controller and model.
00:13:47.360 It’s important to understand that controllers in Trailblazer are mere dispatchers, focusing solely on directing traffic and delegating business logic to operations, which should drastically reduce the responsibility of controllers in your application. In a typical Rails controller, it’s common to see business logic intertwined with routing. Trailblazer helps alleviate that issue by making it clear where operations and business logic belong.
00:14:41.010 In summary, I believe that utilizing Trailblazer can help developers to better structure their Rails applications while keeping everything manageable. You can mix and match the levels of abstraction to suit your needs, applying only what makes sense for your application structure. It offers a non-intrusive way to incorporate more layers without having to discard the Rails structure you’re already familiar with.
00:15:29.180 As we proceed with this talk, I encourage you to ask questions and see how other implementations of Trailblazer can benefit your workflow. This framework is worth exploring and experimenting with it to gain a better understanding of how it can enhance your development process and code quality.
00:16:02.220 Let's move forward with a live demonstration by my friend Jay Austin, who will showcase how to structure Rails applications using Trailblazer. I'm excited to see what he has prepared for us.
00:16:31.210 Thanks to Nick for that introduction! Trailblazer allows for a clean separation and an intuitive flow of handling logic. The way we structure operations enables us to build upon existing functionality without massive overhead. I’ve built a simple blog using Trailblazer, showcasing how we can implement functionality while keeping our controllers and models clean and concise. The process of creating posts includes nested attributes and validations—all handled elegantly through Trailblazer's operations.
00:17:34.150 In my implementation, the controller remains lightweight: it merely initiates operations without embedding business logic directly. The operations focus on the core domain logic while the controller focuses on user routing. Let's see how this results in a more manageable and clean application.
00:19:20.790 You’ll see that operations can seamlessly integrate with Active Record while allowing for multiple model interactions in a clear, consistent manner. Each operation can define what it needs—making it simple for you to keep track of the domain logic against the backdrop of a much slimmer controller.
00:20:53.200 With Trailblazer, you can chain operations within your application logic. If you structure your operations properly, each one becomes a clear responsibility with defined inputs and outputs. This significantly reduces the cognitive load for new developers coming into a project, as they can quickly grasp where the business logic resides and how each piece interacts with the others.
00:22:38.120 Remember, the aim is to have a cohesive setup that minimizes complexity while maximizing clarity, readability, and maintainability. As Nick highlighted, using a high-level architecture in your Rails applications is crucial for sustainability. Trailblazer embraces this complexity by making it more manageable through clear abstractions it provides.
00:24:29.860 In conclusion, leveraging operations and clearly defined layers will result in a Rails application that is much more resilient to changes without falling into chaos. I encourage everyone to adopt Trailblazer and see how it can efficiently streamline your Rails applications.
00:25:07.480 Thank you all for your attention today! If you have any questions or would like further clarifications, please feel free to ask. I look forward to seeing how you can implement these ideas into your own projects.
00:26:02.550 Remember to check out the official Trailblazer documentation and resources. It's been great sharing this time with you, and I hope this knowledge propels you to develop more efficient and cleaner Rails applications. Thank you again!
Explore all talks recorded at RailsConf 2015
+122