Agile Web Development with Ruby and Rails Prof
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 Add. Price. To. Product < Active. Record: : Migration • def self. up • add_column : products, : price, : decimal • • end • def self. down • remove_column : products, : price • end
20091030111023_add_price_to_product • class Add. Price. To. Product < Active. Record: : Migration • def self. up • • add_column : products, : price, : decimal, : precision => 8, : scale => 2, : default => 0 • end • def self. down • remove_column : products, : price • end
Two ways of Generating Migrations • Create a Model • E. g. generating a model called Discount will also generate a migration: • ddddddd_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 Add. Price. To. Product < Active. Record: : Migration • def self. up • • add_column : products, : price, : decimal, : precision => 8, : scale => 2, : default => 0 • end • • end
Anatomy of a migration • class Add. Price. To. Product < Active. Record: : Migration • def self. up • • add_column : products, : price, : decimal, : precision => 8, : scale => 2, : default => 0 • end • def self. down • remove_column : products, : price • end
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 My. SQL
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. Order. History -> Order. Note) • 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. . . • Active. Record: : Base. establish_connection(: adapter => “jdbcmysql”, : database => “development” Connect to the database • class Order < Active. Record: : Base • end • order = Order. find(1) • order. name = “Paul Krause” • order. save 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. . .
- Slides: 22