Blog

Thoughts from my daily grind

Custom Primary Keys in Ruby on Rails

Posted by Ziyan Junaideen |Published: 02 April 2022 |Category: Ruby on Rails
Default Upload |

Rails by default assume an application to have an auto-increment index. Not every model requires a primary key that is an auto-increment integer. Since Rails 4, we have the ability to define a custom index.

When we create a migration, we will have to info create_table that we don't require an ID. Then we need to specify the primary key we intend to use.

In the following example, I require to create a model Country with a primary key set to code which is the ISO code of the country.

class CreateCountries < ActiveRecord::Migration[7.0]
  def change
    create_table :countries, id: false, primary_key: :code do |t|
      t.string :code, null: false
      t.text :description

      # ...

      t.timestamps

     # You probably would want `code` to be unique. In that case...
      t.index :code, unique: true
    end
  end
end

In addition, we need to specify the Primary Key in the model.

class Country < ApplicationRecord
  self.primary_key = :code
end

Now you can create and use the Country model as if code is the primary key ID in other models.

Country.find "UK"
# Country Load (0.2ms)  SELECT "countries".* FROM "countries" WHERE "countries"."code" = $1 LIMIT $2  [["code", "UK"], ["LIMIT", 1]]

If you miss the primary_key config in the modal, you may experience errors similar to:

3.0.2 :004 > Country.last.delete
/Users/jdeen/.rvm/gems/ruby-3.0.2/gems/activerecord-7.0.2.3/lib/active_record/relation/query_methods.rb:1524:in `reverse_sql_order': Relation has no current order and table has no primary key to be used as default order (ActiveRecord::IrreversibleOrderError)

It is nice to see people going beyond the default configuration. It is a good sign that something good and interesting is brewing. Happy hacking!

About the Author

Ziyan Junaideen -

Ziyan is an expert Ruby on Rails web developer with 8 years of experience specializing in SaaS applications. He spends his free time he writes blogs, drawing on his iPad, shoots photos.

Comments