00:00:19.720
So, I gave a talk in San Diego, and Matt gave me my favorite feedback on a talk ever. We walked out, went to happy hour, and afterwards he said, "You know, 30% of what you said I agreed with, and the other 60% your mother would be ashamed of." I wish I could do Matt's French accent to make it even more biting. But hey, French people and math—it’s not my strong suit.
00:00:47.440
I hope that some of you don't like this talk; I hope that you look at some of these ideas and say, "No, I completely disagree," but hopefully in an intellectual way. Your views suck? My views suck too. If you compared a Rails application from 2005 to today, how would you update the view template? Just shout it out.
00:01:14.320
Yeah, rename HTML to RHTML. And that’s it—that's all we’ve done in six years of innovation. We have spent absolutely no time on the view template. The idea I’ve been wrestling with is moving away from the term 'view template' and focusing more on 'the view layer.' As Rails programmers, we have models, which are Ruby classes, and controllers that are Ruby classes, and then there’s this view thing—it’s just a template in some directory. We can start to work on this.
00:01:39.079
Why do we avoid improving the view template? It's hard! It’s the only part of a typical Rails application that mixes four languages: Ruby, HTML, CSS, and JavaScript. Writing view templates is a tricky job. We’ve seen a few people try things like Marabe or other object-oriented view templates, but that’s not the way to go. I’m not a fan of the overwhelming nesting of object code. I think view templates are fine, but there’s room for improvement in this view layer. Just don’t leave the view layer to designers—don’t think that computer science is only found in the model!
00:02:27.360
Controllers tend to suck; we should barely have any code in the controller. But don’t just say, 'Let someone else deal with the view templates.' Instead, we should inject more code into the view layer and improve it. One of my first objections to our implementation of the view layer is the use of instance variables. Explaining how data gets from a controller to a view is complex, and I feel bad when I have to teach new rails classes. The controller and the view don't share context, meaning that a local variable from your 'new' action won’t appear in your new template unless you make it an instance variable.
00:03:26.480
It's still not a shared context, but it’s just there in the view. Well, what would you see if you did this with a view template? I hope you’re asking—what's the answer? It’s complicated. In a really trivial application I wrote with some people who had only been doing Rails for a day, the context size was 51,000 characters. It’s as if they created an anonymous class instance where the instance variables have been copied over from the controller. I'm not pointing fingers; I love Rails. I just think we could do more thinking here.
00:04:24.640
In theory, the Rails MVC model has requests going down to the router, to the controller, to the model, to the database, back to the model, up to the controller, and then to the view and out to the user. But in reality, the controller and view components have two responsibilities, which is against Uncle Bob's principle. The controller handles understanding requests and parameters and then provides a half-hearted data interface to the view layer. This part is lacking when we get to the view.
00:05:30.240
When managing the view layer, we have two main tasks: preparing data for output (like formatting a timestamp to suit the designer's preferred style) and combining that data with the template to generate the final HTML. The line between controller and view is blurred; we need to realize that the model doesn't just interact in a vacuum that could be labeled 'MVC.' The model, view, and controller are completely interconnected. If you’re looking at a view template representing the view layer, how do you know what data is available to you? The only way to know is by looking at the controller.
00:06:37.080
That's a very tight coupling! In an API, there’s usually an interface that clarifies how two objects interact, but currently, our views and controllers are intertwined, as helpers. Unfortunately, instance variables are copied over when 'render' is called from the controller, which can be a performance issue, creating and destroying thousands of objects. One approach I think is quite cool is something from Hashrocket in Florida called 'decent exposure.' It helps define a cleaner interface between your controller and view.
00:07:34.080
In a traditional controller and view scenario, you might define methods to expose resources. This allows you to reduce the amount of boilerplate code in your controllers, making them cleaner, and provides a better relationship between views and the data they receive. By using decent exposure, instance variables can be eliminated from your views, thus simplifying the data access problems.
00:08:42.960
Next, I'd like to talk about helpers. Personally, I have a strong aversion towards helpers. I don't dislike them because they exist, but it's frustrating how they’re often perplexing or misused. In Ruby, everything is an object. For example, when I teach people Ruby, I demonstrate how much simpler scenarios can be when we express processes in Ruby compared to C-like languages. But with Rails, we run into the frustration of relying on procedural helpers instead of using object-oriented techniques.
00:09:45.760
Preparing data for presentation is essential, and many people argue that helpers are necessary. For example, timestamps formatted to be human-readable often rely on helpers. But the reality is, most helpers become object-specific and lead to coupling with specific controllers or models. Why not write object-oriented methods instead, utilizing capabilities in the model rather than creating helpers meant for a single model?
00:10:40.760
What if we had methods like 'user.print_name' or 'user.created_at.format' instead of shifting that responsibility to a helper? We can develop a decorator pattern to attach presentation methods to our data models, leveraging Rails helpers directly while isolating formatting logic into a wrapper. This decorator should be placed within its own directory to apply view-specific operations without intermingle with the model.
00:11:49.200
I know critics might raise their eyebrows when they hear about 'view models' or 'model decorators.' But the idea is relatively simple: separate your view logic from your business logic. For example, if I need to provide different JSON requests based on user roles (admin, authenticated, public), it's often easier to do in a view-specific context. We shouldn’t approach it like a single, monolithic application but as distinct interactions with individual APIs.
00:12:54.480
This leads to a separation of concerns. You can create a dedicated decorator that adapts data models for specific displays depending on the user’s permissions, encapsulating authorization logic within the decorator classes. This means when you serve different users, you have adaptable responses. It’s akin to configuring the output format based on the user type, reducing the complexity in your controllers while promoting reusability.
00:13:59.040
Next point: the need for an interface. Ruby offers a lot of flexibility, allowing one to alter classes on-the-fly, which can be dangerous. However, functions like 'attr_accessible' serve to protect against mass assignment issues. With a properly routed decorator, we can establish a clear interface within the view, dictating which methods are permissible and disallowing access to potentially dangerous queries like those performed directly on the database.
00:15:04.200
The project I've been exploring is called Draper, which is an implementation of the decorator pattern in Rails. I’m excited solely because it presents a productive avenue where you can define what methods a view can call without compromising security. It’s been fun developing this project, and I’ve received interest from fellow developers wanting to implement it.
00:16:32.640
Now, let’s transition into the next section—'View Templates.' What about viewing templates as API customers? A year ago, there was a significant article discussing how downloading HTML is becoming less relevant compared to the increasing dependence on video and media APIs. Not having an API for your product today could mean trouble. Developers expect it—having an API alongside your web application is no longer a luxury but a necessity.
00:17:51.040
This presents a challenge in building both web interfaces for users and APIs for developers—a dual commitment that can feel unnecessary. But, should controllers be involved with output formats? If controllers operated to gather data, shouldn't they simply provide that data instead of formatting it? If the controllers defined proper interfaces, we wouldn’t need to account for generating HTML or JSON separately.
00:19:01.320
This approach would transform view templates into API consumers equally for HTML. Returns would simply be viewed as API responses, reducing repeated efforts between responses designed for people versus those made for computers. We want to simplify the entire approach to how we deliver responses.
00:20:10.079
In earlier architectures, response strategies were a challenge, and the client faced longer response times, wasting precious resources during data processing. However, if we shift the workload to the back end massively—we’ll see a significant reduction in server load. Instead, if we treat view templates just as API customers, we bridge the gap between the presentation layer and data API.
00:21:38.560
Moreover, as you design your API interactions, you and your JavaScript engines can share the same data without having to argue over different requirements from the backend or front end. The architectural shift here is moving templates from a view-centric flow and adjusting them for modern API usage.
00:22:52.720
Finally, I want to emphasize reducing processing on the server side to enhance the time to first response. This is of cardinal importance, especially in instances with high volumes of simultaneous users. The reality is that a majority of the response in average pages is ultimately ‘template,’ so effectively parsing large strings can transform load management on your server.
00:24:22.640
Embrace the variation on API customers—it swings back and forth on broader ideas of views as objects capable of fetching their presenting data while keeping operations clear. In conclusion, consider using decorators to enhance the understanding and flow between your models and views.
00:25:31.440
Throw out instance variables, boost utilization of your view layers using decorators, and unify your interface between API interactions and traditional HTML views. I show you how to wrap it up today.
00:27:19.560
Ask me questions—my name is Jeff Casimir, and I teach the best Ruby and Rails classes on Earth. If you or your company ever need that, let me know. Thanks for your time!.