DEV Community

Alessandro
Alessandro

Posted on • Edited on

Ruby On Rails Best Practice 2020 (for us)

Introduction

Hi, I'm Alessandro and I'm a member of the dev team Rubynetti.
We are based on Earth, Europe, Italy, Venice; we are a team of 3.
We are 1 senior, 1 almost senior and 1 junior.

We write and maintain different web software for different companies.

Last year I wrote an article with our conventions and best practices.
This year I choose dev.to to write it down.

I hope that this gives us more feedback so we can improve our practice.

These are the conventions and references we are using this year (2020) for our projects with Ruby On Rails. Some of these references come from the past. Others are a work in progress.

1. Boring Rest

This is our big principle when we write web applications.
Boring, conventional and predictable code it's the first and most important point to make easy to maintain complex Rails application.
Became more important when writing code with a team.
From this point of view Derek Prior is our guru.

2. Frontend

We use a mix of Vue and Stimulus.
When things are easy we use stimulus.
When things are complex we use vue.
For the moment we avoid SPA and we prefer to use vue as a widget handler.
We used SPA and vue-routing only for one side-silly-project: a web card game about Venice society.

3. Test

We use the standard Rails suite test.
We use it with fixtures.
Everything very normal.
When we call external API we use VCR gem.
Our test is generally short.
We don't like and we don't use mocks and stuff like that.
Too much code to write and maintain.
We use a lot of rails short controller and model test.
Sometimes we start from a test, other times we explore the situation before and write the test after.
We like tests and we suggest everyone use it.
They save our codebase from a lot of bugs and give us confidence when we change stuff.

4. Interactors

Last year we start to use interactors.
We were in the situation of having big fat models.
A lot of concern. And this gives us headaches.
The interactors seem to use a well-structured way to resolve the issue.
Some times we use also PORO object but we like structured and conventional ways to force to write good and concise stuff.
There are different and clever alternatives.
We choose ActiveInteraction because it's easy to integrate inside Rails projects and can handle form errors.

How we use it?

When things are easy we NOT use interactors and we use standard Rails Way.
We like simple things and we like to avoid writing too much code.
Sometimes the thins became complex.
When this happens we use interactors.
Our rule is similar to the Ruby Style Guide.
We try to avoid class more length than 100 lines and methods with more than 10 lines).
We like short methods and short classes.

5. Filter and callback

We don't like and we don't use it. Sorry DHH.
It's the only thing that we don't like about Rails.
I promise.
The problem is that we think that can be very dangerous because they hide complexity and the flow of the code.
Sometimes someone can forget the callback and can generate a lot of problems with data mailer etc.
We use it only in some rare cases when the convenience is big or when we take a legacy project and refactor are too big.

6. Gems

  • Haml \ Slim
  • Pundit (we say goodbye to Cancancan because we like simple things)
  • Devise
  • Webpacker \ Vite
  • Ransack
  • Filterrific
  • ActiveInteraction

New features of Rails 6
We like e we use a lot 2 new features of Rails:

  • ActionText with Trix editor
  • ActiveStorage instead Paperclip (sometimes we prefer carrierwave)

Mailer organization

Our best practice in the past:

N.B. This document is working in progress.

Top comments (5)

Collapse
 
pepetorres1998 profile image
Jose Antonio Torres Garibay

Great post! I din't understand what you were referring in the point 5: Filter and callback. Are you referring to the before_action, after_update, etc hooks?

Collapse
 
simonini profile image
Alessandro

Yes :-)

Collapse
 
pepetorres1998 profile image
Jose Antonio Torres Garibay

And in example, where I work we have an after_update on a model that is a Transaction and it checks if the updated attribute is status and if it is then recalculate the PromissoryNote attached to that Transaction (is a simplified example), without using that hook where can you put that logic?

Thread Thread
 
simonini profile image
Alessandro

Normally we work on controller and put it inside an interaction (github.com/AaronLasseigne/active_i...) or service object. The solution some times is more verbose but the developer regain control. When you are developing a prototype can be a good idea use "callback and friends" to go faster but when things get complicated we try to avoid it. This rule is not a strict rule but a suggestion to avoid "callback hell"

Thread Thread
 
pepetorres1998 profile image
Jose Antonio Torres Garibay

Thanks man! I'd seriously take this in consideration, we might be in callback hell already 😅