Services & Decorators in Rails

From what I can see from the learn repo, you use pretty much a straight Rails MVC pattern.

First of all, is this assumption correct? If it is, have you considered using services and/or presenters/decorators?

And be using I mean all the time, so that no model instance gets to the view, most application logic stays in the services layers and presentation related methods go to the decorators.

What’s your opinion on these concepts?

Thanks.

Yes, I’d say you’re correct. I don’t think we have any presenters in the codebase right now, and not a lot of decorators.

I’d be interested in trying what you’ve described (particularly the “no models in the view” part). I’m curious if the additional level of indirection would pay off. Hard to say without actually trying it.

It has some nice things to it, mostly because of the decoupling of views and models responsibilities. It’s also nice to use Facades, and stuff like that.

The pain comes when form_for does not work as expected, and all the other helpers for which rails assume you have a model (or at least something that quacks like one).

It’s definitely a trade-off.

I was wondering if you had given it some thought and ruled against it. As it isn’t so, would love to hear from you when/if you get to try it.

We’ve discussed it in our weekly development discussion in the past. I believe the consensus was that we’d likely be fighting with Rails’ expectations too much (as you described), making it not worth it.

That said, I think it’s better to try things before ruling them out. If I started a brand new app, I’d strongly consider trying this approach.

1 Like

For your problem with form_for, you can use form objects. You can do it from scratch or use a gem like reform.

I think the form objects are very useful and flexible. What you think?

Form objects are definitely a bit of overhead to get set up properly, but they make any multi-model form or submission with lots of conditional validation logic so much easier to test. I don’t use the exact approach that Bryan uses, but the CodeClimate post on seven patterns for avoiding fat models has a nice primer using Virtus.

Note that if you follow that link and you’re using Rails 4, you can replace the three ActiveModel extends lines with a single line:

include ActiveModel::Model

I don’t see why virtus is useful. It just enable to the form to take a hash in the initializer and assign all the params to a attribute. I think it’s easy to do with attr_accessor and a loop with keys and values in the hash. In addition, he don’t manage the relationships between models. It’s not very complicated to do but reform do it.

Furthermore, reform add a structure to do this. For my current project, I did form objects from scratch and I think I went in a bad way. Reform wasn’t ready when I started. Now, if I must to redo the same thing, I would definitively use reform.

I will definitely check out Reform, it looks very interesting.

Yes, I have used Reform and Form objects. Still, it is not as painless as following rails conventions. :wink:

It also makes it harder to use rails url helpers, i18n helpers, etc… Not impossible, though.

Why do you say than it is harder to use i18n helpers with a form object. Can you just extend ActiveModel::Translation?

Yes, but without form objects you don’t have to. And that’s just an example. For almost all the helpers you have to include something, it’s not painless as if you go with rails CoC.

There are many pros in using form objects, services, facades, presenters, etc… But there are also some cons.

I created my own gem for forms objects : GitHub - GCorbel/activeform-rails: Form Objects for ActiveModel. It’s more oriented for rails than reform and maybe simpler.

Can you take a look and say me what you think about this?

Thanks!