Delegating ActiveRecord methods to decorators in Rails

Pasha Kalashnikov
2 min readMar 5, 2024

Hi, my name is Pasha Kalashnikov, and I love decorating ActiveRecord objects.

Why do we need decorators?

Decorators help us to encapsulate the logic of data-presenting which could be tricky sometimes. I saw a lot of projects without decorators, they contain monstrous ActiveRecord models with thousands of lines of code. Please, don’t make the same mistakes, use decorators instead.

After many years of creating decorators, I have created my own approach to building and using decorators. It was implemented in Tramway Decorator: I wrote a little about it in this article.

Iron Man’s Tramway. Just because I can

I think that decorators should contain some delegated methods from ActiveRecord by default. Tramway Decorator already delegates `id` and `model_name`. Maybe more?

What about alternatives?

  • Old and respectful gem Draper contained method delegate_all . I think that it’s an overhead.
  • active_decorator delegates all methods by default. But, in this case, it makes sense cause active_decorator decorates all ActiveRecord objects by default.

Tramway Decorator delegates…

As I said in a previous article, Tramway Decorator is about flexibility, so, it should decorate some methods but not all of them.

Well, Tramway Decorator delegates ActiveRecord update and destroy methods by default since 0.4.3. I think it’s enough for now. Why do we need these methods in Tramway Decorator?

Tramway Decorator can be used not just for presenting objects, but for more complicated tasks. For example, you have a service with tricky calculating, and your model contains too denormalized data. You need an abstraction that helps with normalization.

You create:

class Users::HardCalculationDecorator < Tramway::BaseDecorator
def basic_stats
end
end

user = tramway_decorate User.find(id), decorator: Users::HardCalculationDecorator

# use it for calculations

A couple of weeks ago, we had a quick discussion about delegating in this discussion on GitHub. Please, add your thoughts about in case you want :)

--

--