Tổng quan về Active Record Migration(Phần 1)
Bài đăng này đã không được cập nhật trong 7 năm
Tổng quan về Active Record Migration (Phần 1)
1. Migrations là gì?
- Migrations giúp thay đổi/cập nhật cấu trúc database của chúng ta một cách đơn giản. Hãy tưởng tượng rằng, mỗi Migration tạo ra giống như một phiên bản (version) của database vậy. Ban đầu database của chúng ta không có gì. Bằng cách tạo ra các Migration, chúng ta có thể thêm, chỉnh sửa hoặc xóa các bảng, cột cũng như các mục trong database. Active Record cũng sẽ thay đổi schema của chúng ta tương ứng với những cập nhật đó. Những thay đổi sẽ được cập nhật vào file
db/schema.rb
trong thư mục ứng dụng.
2. Tạo Migration
- Như đã đề cập ở trên, Migration có thể thêm, xóa hoặc chỉnh sửa bảng, cột. Tuy nhiên ở ví dụ dưới đây, tôi sẽ tạo một bảng để làm ví dụ. Chúng ta sẽ tạo một bảng có tên là User. Bảng này chứa hai trường là
name
vàemail
, hai trường này đều có kiểu dữ liệu làstring
. Ta sẽ gõ lệnh sau:rails generate model User name:string email:string
. Ta sẽ thấy một file mới được tạo ra trong thư mụcdb/migrate
, file này sẽ có tên dạngYYYYMMDDHHMMSS_create_users.rb
. Trong đó,YYYYMMDDHHMMSS
sẽ là thời gian của hệ thống khi file này được sinh ra. Đây chính là cách để Rails quản lý các phiên bản của Migration, quyết định các hành động sẽ thực hiện. - Trong file này bạn sẽ thấy nội dung như sau:
class CreateUsers < ActiveRecord::Migration[5.0]
def change
create_table :users do |t|
t.string :name
t.string :email
t.timestamps
end
end
end
Như chúng ta có thể thấy, trường timestamps
tự được thêm vào bảng dữ liệu. Nó sẽ tạo ra hai cột created_at
và updated_at
, chúng sẽ ghi lại thời gian tạo và cập nhật của một bản ghi. Tiếp đến, chúng ta sẽ chạy câu lệnh: rails db:migrate
để cập nhật lại database và Active Record cũng sẽ cập nhật nội dung trong file db/schema.rb
ứng với các thay đổi vừa thực hiện.
File schema.rb
bây giờ sẽ trông như thế này:
ActiveRecord::Schema.define(version: 20170622162316) do
create_table "users", force: :cascade do |t|
t.string "name"
t.string "email"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
end
Ta có thể dễ dàng nhận ra các thay đổi đã được cập nhật. Và hãy chú ý đến phần version: 20170622162316
. Đây chính là phiên bản hiện tại của schema
.
Tiếp theo chúng ta sẽ thử thay đổi bảng User một chút. Ta sẽ thực hiện bằng cách gõ câu lệnh: rails generate migration AddPasswordToUser
. Trong thư mục db/migrate
sẽ xuất hiện file dạng như 20170622162449_add_password_to_user.rb
. Nội dung sẽ là:
class AddPasswordToUser < ActiveRecord::Migration[5.0]
def change
end
end
Chúng ta sẽ thêm cột password
cho bảng User
bằng cách thêm: add_column :users, :password, :string
vào method change
. Bây giờ, nội dung file cập nhật sẽ là:
class AddPasswordToUser < ActiveRecord::Migration[5.0]
def change
add_column :users, :password, :string
end
end
Sau đó chạy lệnh rails db:migrate
để cập nhật thay đổi cho database cũng như file db/schema.rb
. File schema.rb
sẽ có nội dung:
ActiveRecord::Schema.define(version: 20170622162449) do
create_table "users", force: :cascade do |t|
t.string "name"
t.string "email"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "password"
end
end
Ta có thể thấy rằng nội dung file đã được cập nhật, version hiện tại của schema là 20170622162449
.
Không chỉ dừng lại ở đó, method change
sẽ cung cấp cho chúng ta những phương thức sau để cập nhật cũng như thay đổi database:
add_column
add_foreign_key
add_index
add_reference
add_timestamps
change_column_default (must supply a :from and :to option)
change_column_null
create_join_table
create_table
disable_extension
drop_join_table
drop_table (must supply a block)
enable_extension
remove_column (must supply a type)
remove_foreign_key (must supply a second table)
remove_index
remove_reference
remove_timestamps
rename_column
rename_index
rename_table
3. Một vài khái niệm khác
3.1. Up/down method
Ngoài việc sử dụng method change
thì chúng ta có thể sử dụng method up
và down
. Hiểu nôm na một cách đơn giản, nếu bạn muốn thay đổi schema bằng cách định nghĩa các thay đổi vào method up
thì khi bạn muốn hủy bỏ những thay đổi đó, bạn sẽ viết nó vào method down
. Ví dụ khi bạn thêm một cột address
trong method up
thì trong method down
bạn sẽ xóa cột đó đi. Hãy mường tượng nó qua đoạn code đơn giản sau:
class AddAddressToUser < ActiveRecord::Migration[5.0]
def up
add_column :users, :address, :string
end
def down
remove_column :users, :address, :string
end
end
3.2. Rolling Back
Trên thực tế, sẽ có lúc bạn thực hiện thay đổi và sau đó nhận ra rằng thay đổi mình vừa làm không tốt cho database của mình. Bạn không biết làm thế nào để hủy bỏ thay đổi đó, chẳng lẽ sẽ phải tạo một migration khác để làm việc đó (ví dụ bạn vừa thêm một cột thì bạn sẽ xóa bỏ cột đó trong migration mới). Nhưng may mắn hơn, Action Record đã cung cấp cho chúng ta một cách đơn giản hơn để giải quyết vấn đề đó. Đó là câu lệnh rollback
. Khi bạn chạy câu lệnh rails db:rollback
thì nó sẽ quay trở lại version ngay trước của version hiện tại, giúp bạn hủy bỏ các thay đổi vừa làm.
Ta sẽ tiếp tục lấy ví dụ trên làm minh họa. Giả sử như ta vừa thêm cột password
vào bảng User, bây giờ ta sẽ hủy bỏ thay đổi đó bằng câu lệnh rails db:rollback
. Nội dung file schema.rb
bây giờ là:
ActiveRecord::Schema.define(version: 20170622162316) do
create_table "users", force: :cascade do |t|
t.string "name"
t.string "email"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
end
Chúng ta có thể thấy file schema.rb
đã được đưa về version trước đó là: 20170622162316
và cột password
đã bị xóa.
Thêm nữa, nếu ta muốn quay trở lại các một version nào đó xa hơn chẳng hạn. Hãy sử dụng câu lệnh: rails db:rollback STEP=n
trong đó n
là số lần muốn rollback
. Chẳng hạn db:rollback STEP=2
sẽ tương đương với 2 lần chúng ta chạy câu lệnh rails db:rollback
.
Trên đây là một vài chia sẻ ngắn của tôi về Migration trong Active Record. Hy vọng nó sẽ giúp được mọi người hiểu thêm về Migration trong Rails. Rất mong nhận được sự đóng góp của mọi người để tôi có thể hoàn thiện bài viết hơn. Các bạn có thể tham khảo thêm về Migration tại đây
All rights reserved