Rails Tricks
Archive
16 May
Shared examples with Minitest - Rails Tricks Issue 7
Hi, this week I will show how you can achieve a similar behavior to Rspec’s shared examples with Minitest. We will dry the minitest tests by extracting the common parts into modules.
Imagine you generated two scaffolds, one for a “User” object and one for an “Article” object. Your scaffold tests have almost the same code for most CRUD methods, so let’s share them between the tests. To achieve this, we will create a module:

This module uses ActiveSupport::Concern to have a friendlier interface to call methods when this module is included. At that point, we will create a test for displaying the edit page of the CRUD. Instead of naming the instance variable after the actual object, we will use a generic name @subject, and to generate the URL, we will use the url_for helper with the controller generated from the @subject’s class. We need to change both of our controller tests to set the instance variable and to include this module to test the edit endpoint:

We can remove the generated tests for this edit action from each file and run the tests. To dry our tests further, let’s extract the test for deleting, showing, and listing the records and for the new record action:

Extracting the create and update tests are more involving because there are different attributes for each model, but with the help of other instance variables we can extract those too:

I hope the above examples help to extract common parts of your minitest tests into shared examples.
09 May
How to use a specific version of Rails
Hi, this week I will cover how you can use a specific version of Rails should you need it.
If you call rails new, you will use the version of Rails you have installed on your system, but you might work with multiple versions of Rails and want to use a specific one for your new project, or you want to experiment with something with a given version. Experimenting is my most often use case. When fiddling with security issues, I usually generate a Rails app with the affected version.
To generate an app with a specific version, you can pass the version surrounded by underscores to rails new for the first parameter:

This will generate a Rails 6.0.0 application.
If you would want to generate a Rails app with the Rails main repository, you can do that easily too:

If you don’t need an actual Rails app with the whole file structure, you could also use the Rails bug report templates. There is a separate one for various parts of Rails and also a generic one. They all come with an example test if you are testing buggy behavior.
You can also quickly create a single-file Rails app as I described here: A single-file Rails application, but only for experimenting, it is highly not recommended to use that for a real-world project.
That’s it for the week!
02 May
Active Record where tricks - Rails Tricks Issue 5
Hey, this week, I am bringing you Active Record tricks to find records with missing associations or with associated records only, and to negate your conditions.
The first three methods I will cover are all implemented in ActiveRecord::QueryMethods::WhereChain, which acts as a placeholder object for where queries with no direct parameter.
The first method is associated, which generates an inner join SQL query with a NOT NULL condition on the join field. For instance, if you want to find all blog posts in your database with an author, you can achieve it with the following code:

The next method is missing, which does the opposite and returns the records with missing associations:

It is worth nothing that you can specify multiple associations to both methods, so if you would want to find all posts where the author is missing and has zero comments, you can do so by calling Post.where.missing(:author, :comments) or if you want to find all posts where the author is set and has at least one comment, you can call Post.where.associated(:author, :comments).
The third method I want to mention is not, which can be used to negate a where condition:

There is also the not so well-known invert_where method, which inverts the previous where condition. So you can do this:

You can also use it when you define scopes to not duplicate your conditions:

That’s it for this week!
25 Apr
Active Support helpers configuration - Rails Tricks Issue 4
Hi, this week I am bringing you a trick to configure Active Support helpers!
Active Support is a collection of utility classes and extensions to Ruby core and standard library classes. It provides quite a few valuable data formatting helpers, and if you want to change their formatting settings globally, you can do so by utilizing Rails’ localization.
One such a helper is number_to_currency, which takes precision, unit, delimiter, format, negative_format, and strip_insignificant_zeros as options when you call the helper. If you want to strip insignificant zeros globally, instead of passing the same option over and over to the helper in your code, you can just change the option in your locale file:

There is also the number_to_human_size helper, which has delimiter, precision, significant, and strip_insignificant_zero options. You can change those globally in the locale file too:

Dates are also often formatted into specific formats within an application by calling to_s(:date_format), which is deprecated now in favor of to_fs(:date_format). If you want to use a custom format, you can do so in the locale file:

You are probably working with DateTime objects too in your app, so it is a good idea to set the same formats for Time too:

Last week, I mentioned the Array#to_sentence helper, which can be configured globally from the locale file too:

That’s it for this week. Until next time!
18 Apr
Array Tricks - Rails Tricks Issue 3
Hi, this is your weekly Rails Trick!
This time, I am bringing a few Active Support extensions on Array.
The first one is the to_sentence conversion method. By default, it converts the array to a comma-separated list of words, with the last element joined by “and”. For example:

You can specify the words_connector and the last_word_connector if you want to use something other than the comma and “and”:

The next extension I want to mention is the ArrayInquirer. By calling inquiry on an array, you can convert it to an ActiveSupport::ArrayInquirer object. This will give you predicate methods on the string-like contents of the array. For example:

Active Support also adds a few extra access methods to Array. There is from, which takes a position and returns the tail of the array from that position. There is to, which does the opposite and returns the beginning of the array up until the given position.
There is also the including method, which returns a new array including the elements passed to it. and you can achieve the opposite with excluding, which returns a new array excluding the elements passed to the method. excluding is actually implemented on Enumerable in Ruby, but Active Support reimplements it on Array to make it more performant. It is also worth mentioning that excluding is aliased as without.
There are also methods to access, second, third, fourth and the fifth elements of an array. And there is fourty_two, which has an interesting history. Back in the day, we had these helpers up till 10 (if my memory serves me well), and some people were complaining about them, saying they are bloating Active Support. As a response to the criticism, fourty_two was added as a kind of joke to access “the reddit”, implicating that it holds the Ultimate Answer to Life, the Universe, and Everything .
That’s it for this week!