More than a year ago we established Ruby on Rails courses for locals called “Rubyboost”. Briefly, the idea is that anyone at least a bit familiar with programming could boost their skills to become a junior developer in just two months. Then, students who successfully completed the courses are offered a two-month internship in our company. If the probation period goes smooth we hire them. It’s a relatively fair and easy way to enter upon the path of a professional developer, isn’t it?
And, by the way, you wouldn’t believe how many people applied to learn more about Rails programming!
To cut to the chase, having analyzed all the code written by the students we counted more than 50 common Rails mistakes! What was even worse is that every new group made exactly the same mistakes the previous group had made.
So, here is the list of the things that Rails beginners are unaware of/do wrong or don’t do at all. We also included the right-and-wrong code samples to make our advice more clear.
(The most important ones are highlighted with extra bold)
They don’t use automatically generated methods
Usually, both the Rails framework and many other gems add useful helper methods to the objects they employ. For example, Rails automatically adds predicates to the boolean fields. As a rule, the names of these methods end with a question mark. Keep this in mind!
They have no idea where the “N+1” query comes from
It is very important to understand how ORM works with the database. But newbies usually don’t have that. As the result, they hardly use methods like “includes”, “preload” and “eager_load” and have no idea about the “bullet” gem.
In the first case we have the N+1 query that will be sent to the database. “N” is the number of ready homework assignments. There can be 10, 20 or even 100 queries. In the second case there will be just 2!
They don’t use scopes
Scopes allow you to hide the database implementation and uniqualize the code. Furthermore, the code becomes much more readable, because they reveal the intentions of the developer rather than the database structure.
They don’t know the difference between “after_create” and “after_commit”
The model’s data including its new ID in “after_create” is available from the inside but not from the outside because the transaction isn’t completed.
Here is what would happen if, say, I created a record in the database and after that I decided to put its ID into redis or any other storage:
- “after_create” might result in invalid data if the ID is used before the transaction is completed.
- Using “Sidekiq” or any other background worker I could always use “after_commit” to ensure the integrity of my data.
They always use ORM
Although working with objects is unarguably convenient, the whole process is quite slow and demanding on memory. Beginners don’t always understand how the code works and how to improve it.
They don’t know the difference between “dependent destroy” and “delete_all”
Before being removed “dependent destroy” chooses all constrained records, builds their objects, and calls the destroy method for each of them. This approach allows you to remove all constrained data. But it doesn’t work when large volumes of data are involved.
As for “dependent delete_all”, it removes itself through an SQL query. It is fast, but in this case, you will have to take care of database integrity by yourself.
They don’t use methods with a bang
According to the agreements, there are two cases when a bang (!) is added to the name of a method:
- if a method modifies the object on which it is called;
- if a method throws an exception after unsuccessful execution.
They often overlook the second point. If there is something wrong with the code, you have to find it out as early as possible. For example, if you don’t process the results of saving records to the database at all, it’s better to throw an exception to find out which piece of code processes invalid data.
Here, if an invalid article goes to the input, it will be ignored.
They don’t set default fields in migrations
If a model in the field has to have a default value, it should be installed through the database.
They don’t set constraints in migrations
The more limits we put on the base, the more reliable our app will be. And don’t forget about “null:false”. There can’t be a profile without a user.
They don’t write reverse migrations in migrations
If you are not able to roll back, so what’s point in migrations!?
That was the first part of the most common Rails mistakes that beginners do. If you liked the article – don’t forget to share it in your social media.
To be continued…
You can also have a look at the Russian version of the article here.