Oops... your message was not sent

Your message has been successfully sent

Jetruby Blog
Hire Us
Featured Technical Stories Based On Our Experience
Custom Development, Rails

50 Most Common Rails Mistakes: The Ruby Way

It’s been a while since we’ve rolled out our previous article about the most common Rails mistakes that beginner developers usually make. In this regard, we aren’t going to bother you with too much of introduction and get straight to the point. This article will be dedicated to the standard approaches to Ruby development which are also called “the Ruby way”. As usual, the most critical mistakes are highlighted with RED. So, let’s find out what exactly newbies do wrong/forget to do or don’t do at all.

They misuse predicates

A predicate is a method that answers a specific question and always returns either “yes” or “no”. It’s not supposed to affect any other piece of code or perform any additional actions. According to the Ruby on Rails style guides, predicates are followed by a question mark at the end of the method name.

They forget to explicitly use “present?”, “blank?”, and “nil?”

Using “present?”, “blank?”, “nil?” etc. for validation is considered a good practice even you’re totally sure the code is going to work anyway. Keep that in mind.

They don’t use memoization

common rails mistakes
An instance variable is considered “nil” if it’s not declared. With that in mind, you can leverage memoization. Using the first option in the code sample below will perform four requests: two for the user selection, one for the articles selection, and one for the courses selection. However, if you look at the second option, you will see that the number of requests is now down to three: one for the user selection, one for the articles selection, and one for the courses selection.

They forget that first come symbols, then single quotes, and then double quotes

Ruby on Rails guides insist on using minimum syntax. However, following this notion is not a must. If there should be single quotes – we recommend using double quotes, not screening.

They use some random numbers and lines

One of the rules you need to remember at all times is that there shouldn’t be any random numbers or lines in your code.
common rails mistakes

They often choose short or confusing words to name constants

Using short names for constants leads to poor readability and may even cause conflicts. Moreover, the code eventually becomes completely illegible. The only exception may be when creating migration in a table or generating a form in a view.

They excessively use postconditions

Postconditions allow you to make your code even more laconic and readable. However, in some cases, it’s better to avoid using them. For example:

  • when you know the postcondition can be lost in the current code line;
  • when it’s the main condition and, thus, has to be as visible as possible.

They forget to remove unused parameters and variables, and other unused code

It’s extremely important remove unused code. Why? Because doing that becomes much harder over time especially for other developers.

They don’t use “public_send”

Nearly 90% of all the examples on the Internet refer to the “send” method when invoking a method dynamically. But there is also a similar method – “public_send”– which is even more preferable in some cases.

They write long and illegible conditions

Remember: long conditions – especially the ones starting with “unless” – are very close to unreadable. You can give them proper names by placing them into methods.

They think less code is always better

Ruby code should be easy to read and look into. That’s why you should always write your code with the readability aspect in mind. For example, you can outline an important condition by breaking it down to few more lines.

They use obsolete syntax

Despite there are still quite many guides in which you can find old syntax, we recommend sticking to its new version. Firstly, it’s shorter and easier to read. Secondly, it’s better to adhere to a single code style.

They excessively use “when” and “if”

They don’t use rubocop and other tools for code analysis

Rubocop is a great tool that allows you to search for syntactical and other kinds of mistakes.

They don’t fully understand the point about commenting

Ruby is considered a very high-level language that doesn’t need commenting. Instead of writing another comment to your code, try making it more readable.

Wrap up

This was the third part in the series of articles about the most common Rails mistakes that many beginners face on a regular basis. Hope you’ve enjoyed our tips and pieces of advice. If so, don’t forget to tell your friends about the article by clicking these fancy little buttons below! And if you have any development-related questions, you can always ask our experts in the comment section. Stay tuned!

P.S. You can find the Russian version of the article here.

department
This post created by
Web Development Department
Professional website designing and development.
  • Daniel Gaytán

    Thank you for this article, it’s very explicit, easy to follow, read and integrate in common practices.

    Nit pick… you used send instead of public_send in the example of “They excessively use “when” and “if””.

    • Hi, Daniel! We’re glad to hear that! As for your notion, public_send is better than send only in some cases.

  • Giorgio Torres

    I’m a Ruby on Rails dev for not so long. But during my journey I already notice some peculiarities.
    First I congratulate the author about the great article. Very informative and well written.

    But I’d like to suggest a correction or to append a notice for the “About the use of present?, blank? and nil?” section.
    If in the given snippet was `courses` in the place of `course`, and it was an Array or an ActiveRelation (courses = Array.new or some instance of ActiveRelation) both given sections, wrong and right, would be testing very different things.

    In section ‘wrong’ would be testing if courses variable has been initialized (defined). In section ‘right’ would be testing if courses has any element, even though it has already initialized.
    Semantically speaking, I don’t know if I agree that `[].present?` should really result `false`. The way I see `[].present?` should result to true, but that’s not the way it is implemented. Same happens for `blank?`, but not for `nil?`. And for collection types I would add `any?` and `empty?` methods, which I prefer to test `courses.any?` instead of `courses.present?`.

    Thank you!

  • Ruurd Pels

    From what I am reading here I conclude that the found faults are hardly specific to Rails or Ruby. Many of the issues are quite universal.

  • Anne_Ominous

    No, the “new syntax” is NOT easier to read. It is literally more difficult for the brain to interpret.

    Precisely because it is inherently inconsistent.

    :mysymbol and {mysymbol: 3} use different notations for the same thing, and therefore the brain takes extra time to process them.

    On the other hand, :mysymbol and {:mysymbol => 3} are consistent, and literally easier to read, because the brain does not have to process inconsistent notations before realizing they are the same things.

    The only “advantage” of the “new” syntax — and I’d hesitate to even call it an advantage — is that half the time it looks more like JSON.

    You can call the “old” syntax a “code smell” if you want, but from a human engineering (or industrial psychology) standpoint, it is the “new” syntax that stinks. New is not always better.

    • Mark Mekhaiel

      As someone who joined ruby after the hash syntax was changed, I can’t imagine having to use hash rockets every time. One of the first things I do on legacy code is switch them out as they annoy me more than they should do.

      • Anne_Ominous

        You learned it the new, bad way. So it’s no wonder you feel it’s easier to read.

        But I am referring to human interface engineering. It is quite literally harder to read. You may be more comfortable with it, but the time it takes to process inconsistent notations like this is measurably slower.

        The new notation was a bad idea, from the viewpoint of “friendly to your brain”.

        Seriously, the latest generation of programmers seem to have forgotten the decades of human interface research that went into developing GUIs in the first place. If you want evidence, just try to use TweetDeck. While people get used to it, its interface design is a jumble of garbage.

        The same basic principles of interface design apply to reading and understanding code. It takes time for the eye and brain to interpret what they see, and then more time to react or understand. That time is measurable, and has been measured in many studies over many decades. And one of the basic principles of reducing that extra wear and tear (which leads to mental fatigue and eye strain) is: be consistent.

        The “new” notation is not only not consistent, it is inconsistent in a way that does not jump right out at you. That makes it the worst of the worst.

      • Carl Anderson

        I started doing Ruby well before the syntax change, and while I prefer the new syntax overall, you can’t ignore the old as there is still a lot of code written in that style. So regardless of when you started, you have to know both styles, which slows down reading comprehension, as Anne points out. And as this is the only time you can use symbol notation with the colon after the text, I often find myself typing the colon first and need to fix it when my brain catches up to my fingers. That’s due to habits built up over years, but I can’t be the only one that happens to a lot, too.

        That being said, I don’t hate the new syntax, but I’m pretty sure it will still be a very long time before you could forget the old syntax, and there are legit reasons we shouldn’t even if we could.

    • Marcelo Xavier

      Could you please present a study that shows your point on the brain taking more time to process on this specific case? It seems to be based only on common (or your) sense, no offence.

    • This point is not quite a critical mistake, but is more about style guides of a specific team. We’ve chose this option because of the following reasons:
      1) We do think that this way is much easier;
      2) The majority of the Ruby community also use the mentioned style
      3) The syntax matches the one of the named method params

      • 5) The hashrocket has to be used when the key is not a symbol. There are valid use cases for other key types and this inconsistency is maybe my biggest complaint about the “new” hashes.

  • Giorgio Torres

    First I’d like to congratulate you for the great article. Very informative and well written.
    However, I also would like to point some topics out about the section They forget to explicitly use “present?”, “blank?”, and “nil?”

    I’m going to use a counterexample using almost the same code as you used to expose a pitfall on the use of the same methods in Rails.

    Let’s exchange the course method/variable to courses, where this is some collection type, may be Array or an ActiveRelation.
    If you check “courses.present?” it will return false case the collection is empty. I totally disagree with that implementation. In fact I don’t like, because Ruby is very readable and this design decision about the “present?” method was very poor, I believe, and against Ruby’s way.
    So, if you want to check if the courses variable is not nil, i.e., it has some value, independently if the collection has elements or not, you will have to check using the same construction in your ##WRONG## example section.

    This is just something that I think it is worth it to point out because can lead to semantic errors in someone else’s code.

    • Hi, Giorgio! Thank you for such a comprehensive comment!

      As for whether ActiveSupport is useful or not, there is no unanimous decision about this point. Anyway, the example we’ve given in this article is not about ActiveSupport, but is more about the fact that conditions should be explicit.

      Apart from that. you’re absolutely right that it’s better to use “exists?” for ActiveRecord selections. it’s one of the most common mistakes that beginners make – they don’t think about how ORM works inside. We’ve already discussed this point in the first article https://jetruby.com/expertise/common-rails-mistakes-model-database/. Perhaps you could add more examples?

      Finally, we’ve explained the syntax issue in the comments below.

  • In ‘They excessively use “when” and “if”’, every single line is a perfect example of DON’T:

    def somethod(name)
    send(:”process_#{name}”)
    end

    def process_a
    ‘A’
    end

    def process_b
    ‘B’
    end

    Please, never ever do that. Besides this code is inconsistent (ruby developer would either use `private` methods for `process_x`, or `public_send` in `somemethod`,) it results in a totally unreadable and hard-to-understand error message when future us will extend it with `process_c`. The correct solution is:

    case name
    when ‘a’
    ‘A’
    when ‘b’
    ‘B’
    else
    raise NotImplemented, “Method #{__callee__} was called with an unsupported #{name} parameter.”
    end

    • Thank you for your comment about public_send. As you can see, this point is among the mistakes we’ve listed in the article. However, the mentioned example is not quite about this type of mistake.

      Getting back to your code, it’s another very common mistake made by beginners. We would like to elaborate on it.

      First, metaprogramming is not a “magic” tool for processing every possible option. In the example above, metaprogramming is used to make the code more structured, testable, and readable. In a real-world situation, each method will contain more than one line of code making a single CASE statement into a mess.

      Second, there can’t be a situation when there is no method at all. With a proper approach, this is simply impossible. There are 2 options:
      – the “name” param is something defined by a developer and they know exactly the values it can take. So the developer could define all the methods they need.
      – the “name” param is something received from the “outside”. In this case, the “name” should be validated at the entry point, wherein a current class is not responsible for this action.

      Third – which is something that is usually hard for beginners to accept – we’re all humans and we’re prone to make mistakes. But in most cases (except the industries like the Health and the Economy industries that impose high responsibility), it’s best not to write the kind of code to predict all the possible situations. There are a lot of tools and approaches that enable you to make your code more reliable and good looking, e.g. TDD, BDD, code review etc. That’s why should be willing to accept the fact that your code may fail. Using Sentry or Errbit, you’ll be able to receive timely updates and detailed exception logs on the errors in your app. Thus, you’ll be able to fix the stuff you didn’t predict with much less effort.

  • sshaw

    They use obsolete syntax…

    Obsolete? Not really.

    Secondly, it’s better to adhere to a single code style.

    I agree. Which is why 1.9 style is bad:


    # Can't do this with new version
    x="1"
    {x => 123}
    {1 => 123}

    So by using the new version, you’re forced to not stick to a single coding style.

    • Hi, sshaw! We’ve addressed your comment below.

  • sshaw

    Your argument against case is in need of a proper example.

    In general CASES.clear breaks you code. Can’t do that with case.
    At least use CASES.freeze. But of course, depending on how the hash was created, this is not a 100% solution.

    Only in the 21st century (and arguably with a language like Ruby) will you see someone claim that a case statement is “WRONG”.

  • Pingback: Ruby/Rails дайджест #3: TDD вредит архитектуре, видео с RubyConfAU 2017 и новый гем Patme : IT лента новостей ⋆ iAMX - Развлекательно-информационный портал()

New Articles