Миграции в Rails действительно потрясающие.
Если вы не играли с ними раньше, миграция позволяет вам изменять базу данных атомарными шагами, делая обновления (и понижения) намного, намного, намного проще. Каждый раз, когда вы запускаете script/generate model [model_name]
001_create_model_name.rb # Old style
20081016230401_create_model_name.rb # New style
Конечно, сценарии миграции не новы, но отличия Rails заключаются в том, что они абстрагированы, поэтому в них не задействован SQL (если только вы не хотите использовать SQL, который есть). Код котельной плиты для миграции выглядит примерно так:
class CreateModelName < ActiveRecord::Migration
def self.up
create_table :model_name do |t|
t.timestamps
end
end
def self.down
drop_table :model_name
end
end
Два метода, up
down
up
down
up
create_table
drop_table
Если бы нашей модели model_name
title
author_id
active
class CreateModelName < ActiveRecord::Migration
def self.up
create_table :model_name do |t|
t.string :title
t.integer :author_id
t.boolean :active
t.timestamps
end
end
def self.down
drop_table :model_name
end
end
Прелесть абстрагирования таких вещей в том, что вам не нужно беспокоиться о нюансах между базами данных. Например, логическое значение представляется в виде небольшого целого числа при использовании MySQL, в то время как SQLite имеет собственный логический тип. Однако, если вы используете миграцию Rails, вам не нужно беспокоиться об этом: Rails позаботится об этом за вас.
Что вы, возможно, не поняли, так это то, что полная среда Rails загружается при запуске миграций, так что вы можете фактически запустить код для выполнения задач, которые были бы действительно трудными (или даже невозможными) с помощью простого SQL. Например, может быть, вы хотите создать дополнительный столбец, содержащий версию документа со всеми тегами html
В этом случае вы можете получить миграцию, которая выглядит следующим образом:
class AddStrippedContent < ActiveRecord::Migration
def self.up
add_column :stories, :stripped, :text
Stories.find(:all).each do |s|
s.stripped = s.content.strip_tags
end
end
def self.down
remove_column :stories, :stripped
end
end
Я считаю, что эта функция действительно полезна для установки значений по умолчанию, таких как пользователь по умолчанию для администратора или категории по умолчанию.
Наконец, чтобы запустить миграцию, просто наберите:
rake db:migrate
и для перехода на конкретную версию просто добавьте переменную среды VERSION:
VERSION=4 rake db:migrate
Как видите, это намного проще, чем запоминать эквивалентные команды в SQL!