Change Database Column Type in Ruby on Rails 7

In Ruby on Rails, it's easy to change a column type in your application database. Say we have an online shop, and the prices of the products are integers. But now, we want decimals. How can we achieve that? In this post, we'll talk about how we can do that using Ruby on Rails 7 and Ruby 3.1.2.

Set Up a New Application
 

Let's first create a new application. In the terminal type:

rails new my_shop 

Let's change the directory to the my_shop/ folder:

cd my_shop

Let's quickly generate a scaffold for the Product resource:

bin/rails g scaffold Product title:string price:integer

Initially, the price is an integer. Let's run the migration:

bin/rails db:migrate

Let's set the root route to the products index action. In config/routes.rb, put this at the top of the Rails.application.routes.draw do block:

root 'products#index'

Change the Column Type From Integer to DECIMAL

Now, we'll change the Price column type to decimal. First, let's generate a migration file from the terminal:

bin/rails g migration ChangeProductsPrice

This command generates a migration file with an empty change method. We'll use the reversible method to help Active Record understand what to do in case of a rollback. We'll use the up and down methods. The up method runs when rails db:migrate command is issued, and the down method runs when rails db:rollback method is issued. Let's fill the change method as follows:

def change
  reversible do |dir|
    change_table :products do |t|
      dir.up   { t.change :price, :decimal }
      dir.down { t.change :price, :integer }
    end
  end
end

When rails db:migrate command runs, the price will be a decimal. When rails db:rollback command runs, the price is an integer.

By the way, in the app/views/products/_form.html.erb file, you will want to change the number_field helper to a text_field helper because the number_field helper generates an input with the type attribute in the number state, which lets you enter only integers in the user interface.

Then we restart the server, and from now on, all the products we add to the database will have a decimal type.

Post last updated on May 13, 2023