Have you ever got annoyed with data types when you are creating Rails migrations?
What’s the full list of data types in Rails? Does it differ from MySQL to PostgreSQL?
When adding a title field to Post table, should we use title as a string or text? Same answer with MySQL and PostgreSQL?
You may want to check the Rails guides of Active Record Migrations, but all you get is disappointment because its lacking of essential information about data types.
Here is a quick entry about data types which I extracts from Rails API and Stack Overflow.
$ rails generate model -h
Available field types:
Just after the field name you can specify a type like text or boolean.
It will generate the column with the associated SQL type. For instance:
`rails generate model post title:string body:text` will generate a title column with a varchar type and a body column with a text
type. If no type is specified the string type will be used by default.
You can use the following types:
integer
primary_key
decimal
float
boolean
binary
string
text
date
time datetime
You can also consider `references` as a kind of type. For instance, if you run:
`rails generate model photo title:string album:references` It will generate an `album_id` column. You should generate these kinds of fields when
you will use a `belongs_to` association, for instance. `references` also supports
polymorphism, you can enable polymorphism like this:
`rails generate model product supplier:references{polymorphic}` For integer, string, text and binary fields, an integer in curly braces will
be set as the limit:
`rails generate model user pseudo:string{30}` For decimal, two integers separated by a comma in curly braces will be used
for precision and scale:
`rails generate model product 'price:decimal{10,2}'` You can add a `:uniq` or `:index` suffix for unique or standard indexes
respectively:
`rails generate model user pseudo:string:uniq``rails generate model user pseudo:string:index` You can combine any single curly brace option with the index options:
`rails generate model user username:string{30}:uniq``rails generate model product supplier:references{polymorphic}:index` If you require a `password_digest` string column for use with
has_secure_password, you should specify `password:digest`:
`rails generate model user password:digest`
:string | VARCHAR | :limit => 1 to 255(default=255):text | TINYTEXT, TEXT, MEDIUMTEXT, or LONGTEXT2 | :limit => 1 to 4294967296(default=65536)
So you’d better specify the :limit as a reminder to yourself that there is a limit and you should have a validation in the model to ensure that the limit is not exceeded.
And, you can have indexes on varchars, you cannot on text.
There is no performance difference among these three types, apart from increased storage space when using the blank-padded type, and a few extra CPU cycles to check the length when storing into a length-constrained column. While character(n) has performance advantages in some other database systems, there is no such advantage in PostgreSQL; in fact character(n) is usually the slowest of the three because of its additional storage costs. In most situations text or character varying should be used instead.
There’s no reason to use :string (AKA varchar) at all, the database treats text and varchar(n) the same internally except for the extra length constraints for varchar(n); you should only use varchar(n) (AKA :string) if you have an external constrain on the column size.