[Tutorial] View Objects – The Way to Deal with Messy Rails Views

As your view begins to contain more complex logic, you can encounter all kinds of problems. First, it can be problematic to test. Second, your code becomes less readable and harder to modify. That’s when View Objects might help you: https://www.nopio.com/blog/view-objects-rails-views/

1 Like

Don’t extract Mixins from bloated models

I understand that decoration, in general, is a better choice than mixing. But what bad can happen if you include presentation logic into your model? Yes, you can’t inherit from a module but do you really need to have OOP in some kind of view helpers? I see several profits of using ‘include ArticlePresentation’ in your AR classes: the inclusion is explicit; no extra code is required; no problems with interacting with other libraries such Kaminari.

Using complex nested data. You should avoid expressions that have more than one dot like order.vendor.brand.name

Why? Isn’t it easier to understand than order.vendor_name? When I think about an app I usually think about DB, models and how the tables are connected. When you are hiding some letters from order.vendor.brand.name you just make a new entity vendor_name. You force a reader of your code to think: “is it an attribute?”, “is it a delegation in Order model?”, “is it some kind of magic method from somewhere?”.

When it comes to view logic, a better solution is to put it inside of a decorator class. A class that’s sole responsibility is to decorate objects that then are displayed in views. Inside decorators class you should only have view-related logic so you know exactly what it is responsible for. This way of doing it makes the code cleaner than using a module. Of course this is not a rule, one can use modules for view logic, but you loose the ability to easily decorate an object differently per context. For example, you can have separate decorators for each view.

As a rule of thumb, I see modules as containers for business logic ( that wasn’t yet moved to service objects :wink: )

When it comes to view logic, a better solution is to put it inside of a decorator class.

Yeap, I got the idea behind the decoration way. I see that decorators are more powerful. Do you really decorate the same modules with different decorators? It can become really complex. My question is: “but what bad can happen if you include presentation logic into your model?”.

This way of doing it makes the code cleaner than using a module

Why? You can put modules in /app/presentation/. E.g. your /app/models/article.rb includes /app/presentations/article_presentation.rb

As a rule of thumb, I see modules as containers for business logic

Modules are just modules. It’s part a part of Ruby. You can do with them whatever you want.

If name of method is reasonable nobody should have problem with understanding it. The second thing is that method like vendor_name can be reusable and you don’t need to remember every time all models attributes to use it.

Answering your question: “but what bad can happen if you include presentation logic into your model?”. It’s simple, you’ll end up with a huge model class that has many dependencies and use contexts. Good luck with creating easy to follow tests for it. Also, it’s a nightmare for any new person joining the project. You need to change how data is displayed? First go through logic mixed with view related functions :wink:

Your second point. If you go through problem of adding special structure for view related modules why wouldn’t you spent the same time to use decorators and not limit your options.

1 Like