Change Database Column Type in Ruby on Rails 7
In Ruby on Rails June 4, 2022
Updated on May 13, 2023
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.