Common Rails Database Q&A
Q&A on using ActiveRecord and Databases in Rails, based on popular StackOverflow questions. See Models and Data for a beginner's intro to Rails Models.
How can you duplicate a record?
Let's say you have a nice product record and you want to create a variant of it that will have some slight differences. You can copy it with .dup:
prod1 = Product.first
=> #<Product id: 1, name: "Cow", description: "Moos, eats grass.", price: 10, created_at: "2015-06-29 19:25:38", updated_at: "2015-06-29 19:25:38", category_id: 1, quantity: 5, image_url: nil>
prod2 = prod1.dup
=> #<Product id: nil, name: "Cow", description: "Moos, eats grass.", price: 10, created_at: nil, updated_at: nil, category_id: 1, quantity: 5, image_url: nil>
prod2.name = "Zebra"
=> "Zebra"
prod2.save
=> true
prod2
=> #<Product id: 7, name: "Zebra", description: "Moos, eats grass.", price: 10, created_at: "2015-06-30 21:36:24", updated_at: "2015-06-30 21:36:24", category_id: 1, quantity: 5, image_url: nil>
.dup
copies the columns from the original, except for the id and timestamps (created_at
and updated_at
). It doesn't copy children elements, so prod1's likes will not be copied to prod2.
How can you change a column type?
Let's say your products
table has an integer price
column and you want to change it to a decimal column.
- Generate a migration file, e.g.
rails generate migration ChangePriceToDecimal
- Use the following code to change the column type:
change_column :products, :price, :decimal
- Officially, your migrations should be reversible. To do this, replace the
def change
method in the migration file withdef up
anddef down
methods:
class ChangePriceToDecimal < ActiveRecord::Migration
def self.up
change_column :products, :price, :decimal
end
def self.down
change_column :products, :price, :integer
end
end
(See the Rails Migrations Guide and StackOverflow Answer for more info.)
What data types can you use in Rails columns?
Rails supports many different types of columns, as mentioned in the docs. The details of how each one is stored will depends on the database you're using, but you can see examples of each type below. (See also StackOverflow).
When you retrieve an item's data from a database, Rails will automatically set the correct class for it. For example, say you have a products
table with string column name
:
prod = Product.first
name = prod.name
name.class #String
Numbers
type | examples | Ruby Class | note |
---|---|---|---|
:integer | 4368, -11 | Fixnum | store positive or negative integers |
:float | 2.000001 | Float | store decimal places |
:decimal | 3.01, 150.375 | BigDecimal | stores decimal places more precisely than float (e.g. for currency) |
Text
Both these types use the Ruby class String.
- :text - general text column
- :string - text that you know will never be longer than 256 characters. (See StackOverflow.)
Date & Time
Usually you can just use DateTime.
type | example | Ruby Class |
---|---|---|
:time | 2015-06-30 21:15:16 | Time |
:date | 2015-07-01 | Date |
:datetime | 2015-06-30 21:15:16 | DateTime |
timestamp | Fri, 03 Jul 2015 00:00:00 UTC +00:00 | ActiveSupport::TimeWithZone |
Other
- :binary - for storing binary data such as images or audio
(note that such data should often be stored outside the database) - :boolean -
true
orfalse
- :primary_key - unique key to identify each record in table. By default every table has an ID column that is used as the primary_key.
(You can also create a references
column, though that isn't really its own datatype.)
Your database may also support additional datatypes.