How Trailblazer Makes Ruby on Rails Better?
What makes Ruby on Rails so special?
Before digging into Trailblazer, let’s praise Rails a bit. Ruby on Rails is a web application framework that is known for rapid prototyping. You could think of a Rails app you want to build and have it up online and ready to go within a few hours. Check out some of these examples of websites that are built with Rails: Hulu, Airbnb, Basecamp. Rails is so fun for beginners is because it’s really really robust and it does SO MUCH of the hard work for you.
What is Trailblazer?
Every once in awhile someone comes along who questions the integrity and very nature of their surroundings, and meanwhile, points out the flaws in the already so called ‘perfect’ system. Nick Sutterer aka Apotonick is such a man who wasn’t happy with the existing three abstraction layers, called “MVC” of Rails and introduced questions such as:
“What price do we pay for Rails’ simplicity in trade for maintainability?”
“Is it worth writing models with thousands of lines of code and building a throw-away software kludge that is impossible to maintain, just for the sake of development speed?”
“Is it worth blindly hacking away and following the Rails conventions without thinking about whether this is the right place for that code?”
Hence, the birth of Trailblazer. A high level architecture for Rails. Trailblazer sits on top of Rails to introduce better abstraction layers, structure and reasonable encapsulation.
Technical aspects of Trailblazer
The diagram is to be understood from top to bottom, where the top represents the incoming request endpoint and the bottom compiles the response.
- Controllers become lean HTTP endpoints. They handle authentication (if not handled elsewhere), differentiate between request formats like HTML or JSON and then instantly delegate to the respective operation. No processing logic is to be found in the controller.
- An operation contains all the business logic.
- Every operation validates its input using a form object.
- Models are lean persistence endpoints. No logic but configuration is allowed in model classes.
- Operations and forms can change and persist models.
- Representers can be used to parse incoming documents and to render API representations. Since form objects internally use representers they can be used for that directly without having to specify a representer.
- Controllers can render views or delegate to Cells (a.k.a. View Models) and provide a better abstraction for rendering complex UIs.
- Controllers might also use responders to render responses. Cells and operations can be passed directly into a responder and completely remove the rendering logic from controllers.
- Operations replace test factories, and can be used in scripts and console, too.
While Trailblazer showcases a lot of advancements, I will be discussing my favorite ones in short below.
1. Logicless Models
A model in Trailblazer looks like this. Innocent, beautiful, and without any business logic.
Question: Then where does the business logic and validations go?
Answer: The business logic for both reading and writing along with validations is abstracted into new layers: Operation, Form and Twin are patterns that Trailblazer brings to your architecture.
In Trailblazer, the implementation of a high-level function goes into an Operation. Surprisingly, this is a class!
No business logic in controllers and an immediate dispatch to the target operation are fundamental concepts of Trailblazer.
3. Concepts and File Structure
In Trailblazer, you structure your app by domain into real components.They are called concepts. You implement a concept for every entity in your high-level domain. That means you have comment, profile, thing, feed, or a dashboard concept. Those concepts sit in app/concepts in their own directory. All classes and views belonging to that concept, forms, operations, and so on, are in that very directory.
An operations lets you define a form object, or contract. Internally, this simply creates a Reform⁶ form class.
In the contract block you can define properties of your form and their validations. This means you don’t have to make your model messy.
Rails comes packed with a lot of callbacks and a few very confusing ones, such as: around_save and around_create.
Operations provide a clean way to group callbacks. Instead of adding ActiveRecord callbacks with conditionals you explicitly invoke the hooks in your operation class. In Rails, this is often done with ugly :unless or if: lambdas and the like. You never know whether or not a callback gets triggered when saving an object. This creates fear. In Trailblazer, you ideally expose a new operation if you decide you need the same behavior without any “callbacks”.
Cells provides proper object-oriented encapsulation for views. Cells let you implement parts or blocks of your UI in a separate component, like a separated mini-MVC stack.
The above snippet could be in a controller view or the application layout. Here, the concept helper will call the cell’s #show state. Note that I pass the latest comment model into the cell – every cell requires an object to wrap, whether that is a model, a collection or an OpenStruct is completely up to you. And now guess how a cell is implemented? Right, as a class!
Per convention, the #show method is invoked once the cell is used. The above state does nothing more but rendering its view. Cell views are not in the global directory. They are components so views do reside in the concept’s view directory, for instance app/concepts/comment/views/show.haml. At first glance, cell views look identical to ordinary views in Rails.
“This view is nice and tidy. That doesn’t look like an ordinary Rails view!” you might think now, and you’re correct. In Cells, instance variables and locals are still available but proscribed. The preferred way of getting data into the view is with reader methods.
Apart from the features briefly mentioned above, Trailblazer comes packed with a lot of cool features and gems functional together to make the Rails’ way awesome! Due to its success, Trailblazer 2.0 is out now. Make sure to check it out at http://trailblazer.to/ or you can download the book which is completely free from https://leanpub.com/trailblazer.