This blog is part of our Rails 5 series.
Database schemas change rapidly as project progresses. And it can be difficult to track purpose of each table and each column in a large project with multiple team members.
The solution for this problem is to document data models right from Rails migrations.
Solution in Rails 4
You can add comments in Rails 4.x migrations using gems like migration_comments and pg_comment.
Solution in Rails 5
Rails 5 allows to specify comments for tables, column and indexes in migrations.
These comments are stored in database itself.
Currently only MySQL and PostgreSQL supports adding comments.
We can add comments in migration as shown below.
1class CreateProducts < ActiveRecord::Migration[5.0] 2 def change 3 create_table :products, comment: 'Products table' do |t| 4 t.string :name, comment: 'Name of the product' 5 t.string :barcode, comment: 'Barcode of the product' 6 t.string :description, comment: 'Product details' 7 t.float :msrp, comment: 'Maximum Retail Price' 8 t.float :our_price, comment: 'Selling price' 9 10 t.timestamps 11 end 12 13 add_index :products, :name, 14 name: 'index_products_on_name', 15 unique: true, 16 comment: 'Index used to lookup product by name.' 17 end 18end
When we run above migration output will look as shown below.
1➜ rails_5_app rake db:migrate:up VERSION=20160429081156 2== 20160429081156 CreateProducts: migrating =================================== 3-- create_table(:products, {:comment=>"Products table"}) 4 -> 0.0119s 5-- add_index(:products, :name, {:name=>"index_products_on_name", :unique=>true, :comment=>"Index used to lookup product by name."}) 6 -> 0.0038s 7== 20160429081156 CreateProducts: migrated (0.0159s) ==========================
The comments are also dumped in db/schema.rb file for PostgreSQL and MySQL.
db/schema.rb of application will have following content after running products table migration .
1ActiveRecord::Schema.define(version: 20160429081156) do 2 3 # These are extensions that must be enabled in order to support this database 4 enable_extension "plpgsql" 5 6 create_table "products", force: :cascade, comment: "Products table" do |t| 7 t.string "name", comment: "Name of the product" 8 t.string "barcode", comment: "Barcode of the product" 9 t.string "description", comment: "Product details" 10 t.float "msrp", comment: "Maximum Retail Price" 11 t.float "our_price", comment: "Selling price" 12 t.datetime "created_at", null: false 13 t.datetime "updated_at", null: false 14 t.index ["name"], name: "index_products_on_name", unique: true, using: :btree, comment: "Index used to lookup product by name." 15 end 16end
We can view these comments with Database Administration Tools such as MySQL Workbench or PgAdmin III.
PgAdmin III will show database structure with comments as shown below.
1-- Table: products 2 3-- DROP TABLE products; 4 5CREATE TABLE products 6( 7 id serial NOT NULL, 8 name character varying, -- Name of the product 9 barcode character varying, -- Barcode of the product 10 description character varying, -- Product details with string data type 11 msrp double precision, -- Maximum Retail price 12 our_price double precision, -- Selling price 13 created_at timestamp without time zone NOT NULL, 14 updated_at timestamp without time zone NOT NULL, 15 CONSTRAINT products_pkey PRIMARY KEY (id) 16) 17WITH ( 18 OIDS=FALSE 19); 20ALTER TABLE products 21 OWNER TO postgres; 22COMMENT ON TABLE products 23 IS 'Products table'; 24COMMENT ON COLUMN products.name IS 'Name of the product'; 25COMMENT ON COLUMN products.barcode IS 'Barcode of the product'; 26COMMENT ON COLUMN products.description IS 'Product details with string data type'; 27COMMENT ON COLUMN products.msrp IS 'Maximum Retail price'; 28COMMENT ON COLUMN products.our_price IS 'Selling price'; 29 30 31-- Index: index_products_on_name 32 33-- DROP INDEX index_products_on_name; 34 35CREATE UNIQUE INDEX index_products_on_name 36 ON products 37 USING btree 38 (name COLLATE pg_catalog."default"); 39COMMENT ON INDEX index_products_on_name 40 IS 'Index used to lookup product by name.';
If we update comments through migrations, corresponding comments will be updated in db/schema.rb file.