Igor Petrov

@igor.petrov

5 Ruby on Rails Tips You Probably Don’t Know

Since I started working with Ruby on Rails, and after several years of using it passed by, I can’t stop wondering when I discover something new in Ruby world. Yes, this is how it works — you know, Ruby is for developer happiness (beyond this there are some other principles) and each year of using it and finding out new stuff supports this feeling inside.

Ok, so this article shares a bunch of stuff I discovered recently. They are rarely used methods and not a must-have in your code, mostly “syntax sugar”, but anyway it will make your code much cleaner. Some stuff is just new changes appeared with new Ruby or Rails versions.

Hash#dig

I didn’t meet this in anyone’s code for 7 years of RoR development and discovered recently. And it’s obvious why :-) The first Ruby version I worked with was 1.8, but this method was introduced in 2.3.

How many times did you do something like this:

... if params[:user] && params[:user][:address] && params[:user][:address][:somewhere_deep]

Think of dig as kind of safe navigation operator &. but for Hash objects. So now you could rewrite such things:

... if params.dig(:user, :address, :somewhere_deep)

Object#presence_in

This one I found in the very good article about Query Objects in Ruby on Rails. It allows you to replace conditionals (often ternary) with single method call when you don’t actually need a boolean result of inclusion check, but a checked object itself. For example, your code looks like:

sort_options = [:by_date, :by_title, :by_author]
...
sort = sort_options.include?(params[:sort]) 
? params[:sort]
: :by_date
# Another option
sort = (sort_options.include?(params[:sort]) && params[:sort]) || :by_date

Doesn’t this look better?

params[:sort].presence_in(sort_options) || :by_date

Module#alias_attribute

Well, I found this very useful when I worked on a project with a legacy database. It had a table with weird column names like SERNUM_0, ITMDES1_0 and other. We mapped this table to an ActiveRecord model and instead of writing queries and scopes on it like WeirdTable.where(SERNUM_0: ‘123’) , we came up to using alias_attribute since it doesn’t just generate getter and setter (as well as a predicate method), but works in queries as well:

alias_attribute :name, :ITMDES1_0
...
scope :by_name, -> (name) { where(name: name) }

Object#presence

This one is more popular than others. There’s pretty good explanation on ApiDock. So, object.presence is equivalent to:

object.present? ? object : nil

Module#delegate

Still rarely used by most of the developers for some reason. The main purpose of this method is loose coupling and following the Law of Demeter. One of the good articles on this theme coming to mind is Avdi Grimm’s “Demeter: It’s not just a good idea. It’s the law.” Also, check out short Rails Best Practices article on utilizing delegate in context of applying the Law of Demeter. The snippet below describes this as well:

class Profile < ApplicationRecord
belongs_to :user
  delegate :email, to: :user
end
...
profile.email # equivalent to profile.user.email

I hope you’ve just discovered some of these tips above and find them useful. Happy coding!

If you liked this post, please click on to spread the word.

More by Igor Petrov

Topics of interest

More Related Stories