Must-have gem for rails projects: zero downtime migrations

This is one of the most useful Ruby gems I’ve discovered in a while: zero_downtime_migrations, it catches problematic migrations at development time.

Problems such as:

  • Adding a column with a default in a single migration;
  • Adding a non-concurrent index;
  • Mixing data changes with index or schema migrations;
  • Performing data or schema migrations with the DDL transaction disabled;
  • Using each instead of find_each to loop thru ActiveRecord objects when doing data changes;

And it doesn’t only catch the problem but it also teaches what you should do to avoid it 👏👏

Example from their README:

Solution of problem and solution

Seriously, share this gem with every Rails developer you know and make everybody’s life a bit easier 😁

Ruby already has its own regular expression to validate emails

I’ve searched and written a lot of regular expressions to validate email on our models and forms but recently I’ve found out that Ruby already has a good one and its easy to access and use.

All you have to do require uri library and use its constant:

require 'uri'

It’s also easy to use on an Active Record format validation:

validates :email, format: { with: URI::MailTo::EMAIL_REGEXP, message: "only allows valid emails" }

It even accepts emails with “+” as gmail enables.


How to solve rails 4 UndefinedTable Error when creating namespaced models

In a given rails 4 application, I have two namespaced models with a has_many association between them:

# models/review/asset_type.rb
module Review
  class AssetType < ActiveRecord::Base
    belongs_to :review_asset_category, class_name: Review::AssetCategory

# models/review/asset_category.rb
module Review
  class AssetCategory < ActiveRecord::Base
    has_many :review_asset_types, class_name: Review::AssetType,
             foreign_key: 'review_asset_category_id'

With migrations as:

class CreateReviewAssetCategories < ActiveRecord::Migration
  def change
    create_table :review_asset_categories do |t|
      t.string :name
      t.timestamps null: false

The migrations ran well but everytime I ran the tests I received the error:

Failure/Error: it { respond_to(:name) }
       PG::UndefinedTable: ERROR:  relation "asset_categories" does not exist
       LINE 5:                WHERE a.attrelid = '"asset_categories"'::regc...
       :               SELECT a.attname, format_type(a.atttypid, a.atttypmod),
                            pg_get_expr(d.adbin, d.adrelid), a.attnotnull, a.atttypid, a.atttypmod
                       FROM pg_attribute a LEFT JOIN pg_attrdef d
                         ON a.attrelid = d.adrelid AND a.attnum = d.adnum
                      WHERE a.attrelid = '"asset_categories"'::regclass
                        AND a.attnum > 0 AND NOT a.attisdropped
                      ORDER BY a.attnum

The solution is simple, just add this class method to each model or to the module that is namespacing the models:

module Review
  def self.table_name_prefix

I hope this simple advice will save some time for other developers 🙂