Agile Web Development with Ruby and Rails Prof. Paul Krause Lecture 7 Migrations and Active Record
Objectives for today A Look at Migrations From Migrations to Active Record Rails’ Object-Relation Mapping More on Rails Controllers
20091030111023_add_price_to_product class AddPriceToProduct < ActiveRecord::Migration def self.up add_column :products, :price, :decimal end def self.down remove_column :products, :price
20091030111023_add_price_to_product class AddPriceToProduct < ActiveRecord::Migration def self.up add_column :products, :price, :decimal, :precision => 8, :scale => 2, :default => 0 end def self.down remove_column :products, :price
Two ways of Generating Migrations Create a Model E.g. generating a model called Discount will also generate a migration: dddddddddddddd_create_discounts.rb Generate a migration on its own E.g. Generate/Migration add_price_column You then need to ask Rails to run a “Rake” task to migrate to the new version
Anatomy of a migration class AddPriceToProduct < ActiveRecord::Migration def self.up add_column :products, :price, :decimal, :precision => 8, :scale => 2, :default => 0 end
Anatomy of a migration class AddPriceToProduct < ActiveRecord::Migration def self.up add_column :products, :price, :decimal, :precision => 8, :scale => 2, :default => 0 end def self.down remove_column :products, :price
Column Types add_column :orders, :e-mail, :string The third parameter specifies the type of the database column. But databases typically don’t have :string as a type? Rails insulates you from the underlying database by using “logical types” E.g. :string type will generate a column of type varchar(255) in MySQL
Column Options :null => true or false :limit => size :default => value N.B. the value is determined at the time of application of the migration: add_column :orders, :placed_at, :datetime, :default => Time.now decimal columns also support the options :precision and :scale
Summary of migration types Create tables Add columns Rename columns Change the type, or options, of columns Rename tables
Warning about renaming tables If you rename a table (e.g. order_histories -> order_notes), you will also need to rename the associated model (e.g. OrderHistory -> OrderNote) Now, suppose you wish to drop the database, and then reapply all migrations? Rerunning the migration to create the table order_histories will generate an exception, as the associated model has been renamed! There are ways around this, but be aware that Rails migrations are not foolproof...
Primary Keys You will not normally explicitly define a primary key Rails assumes: every table has a numeric (integer) primary key (called id) Rails ensures the value of this column is unique for each row added to the database You can change the name of the primary key: create_table :tickets, :primary_key => :number do |t| .. But it is not a good idea to change the type from an integer
Primary Keys You will not normally explicitly define a primary key Rails assumes: every table has a numeric (integer) primary key (called id) Rails ensures the value of this column is unique for each row added to the database You can change the name of the primary key: create_table :tickets, :primary_key => :number do |t| .. But it is not a good idea to change the type from an integer
Tables with no Primary Key The most common case for this is a join table Need to explicitly tell Rails not to generate a primary key: create_table :authors_books, :id => false do |t| t.integer :author_id, :null => false t.integer :book_id, :null => false end
From Migrations to Active Record
Active Record This is Rails’ Object-Relational mapping: Tables map to classes; Rows map to objects; Columns map to object attributes. The “Rails way” is to use sensible defaults to minimise the configuration needed
Simple Example that Does a Lot... ActiveRecord::Base.establish_connection(:adapter => “jdbcmysql”, :database => “development” class Order < ActiveRecord::Base end end order = Order.find(1) order.name = “Paul Krause” order.save Connect to the database Wrap the table of Orders in the database Find the order with a specific ID Change the purchaser’s name Save the result back in the database
More on the slides from Sun Microsystems ...