12/08/2018, 15:52

Rails Migrations Tricks và CheatSheet

Rails Migration được mọi Rails Developer giới thiệu là một cách dễ dàng và hiệu quả để tạo, thay đổi các cấu trúc trong database, giúp tăng lên hiệu quả công việc, không mất nhiều thời gian. Đối với Rails Developer, Raills migration và Rails generator thường là rất quên thuộc với họ, nhưng không ...

Rails Migration được mọi Rails Developer giới thiệu là một cách dễ dàng và hiệu quả để tạo, thay đổi các cấu trúc trong database, giúp tăng lên hiệu quả công việc, không mất nhiều thời gian. Đối với Rails Developer, Raills migration và Rails generator thường là rất quên thuộc với họ, nhưng không phải ai cũng biết rõ về cách sử dụng chúng một cách hiệu quả và nhanh chóng. Hôm này, mình xin giới thiệu một số tricks cho Raills migration và Rails generator.

Một command line generator để thêm/xóa columns trong database

$ rails generate migration AddFieldNameToTableName // add column 
$ rails generate migration RemoveFieldNameFromTableName field_name:datatype // drop column

Nó sẽ generate ra file migration chứa code như sau:

add_column :table_name, :column_name
remove_column :table_name, :column_name

Ví dụ

$ rails generate migration RemoveNameFromMerchant name:string

=> migration file:

class RemoveNameFromMerchant < ActiveRecord::Migration
  def change
    remove_column :merchants, :name, :string
  end
end

Để xóa table, Rails không có cách magic để minh như command trên. Vậy mình phải tự viết code migration này. Nhưng phải viết thế nào để đảm bảo tính đúng đăn và không có risk cho hệ thông.

$ rails generate migration DropMerchantsTable

Command trên chỉ tạo ra file migration trắng, không tự động có code cho mình. Vậy cách đảm bảo nhất như sau:

class DropMerchants < ActiveRecord::Migration
  def change
    drop_table :merchants do |t|
      t.string :name, null: false
      t.timestamps null: false
    end
  end
end

Nếu bạn dùng drop_table :merchants cũng chạy được, nhưng chỉ là one-way migration tức là không rollback được.

Nếu bạn tạo migration rồi mà không revert lại được, hoặc revert lại sai, hoặc không như cũ thì migration của bạn chưa thật sự tốt. Để rollback lên ở thời điểm file migration nào đó (file migration từ dưới lên), bạn dùng STEP.

$ rake db:rollback STEP=3

=> Rollback 3 step migration từ dưới lên. Nếu bạn muốn rollback migration cuối cùng, bạn có thể bỏ STEP đi được.

$ rake db:rollback

Để tạo giá trị mặc định cho record nào đó, bạn có thể set default với migration.

t.boolean :is_active, default: true

Nhưng không phải lúc nào cũng dùng cách trên được. ví dụ, nếu default value đó cần có điều kiện, hoặc là quan hệ với bảng khác. Trường hợp đó sẽ không set default với migration được. Vậy cách flexible hơn, thì dùng callback after_initialize trong model.

class Merchant < ActiveRecord::Base
  has_one :client
  after_initialize :init

  def init
    self.name  ||= "SuperStore"  # will set the default value only if it's nil
    self.client ||= Client.last  # also setting a default association
    self.in_business = true if self.in_business.nil? # ⚠️ only default booleans to 'true' if they're 'nil' to avoid overwriting a 'false'
    end
  end

Khi nào nên dùng text và string? có gì khác nhau.

  • string: khi migrate ra MySQL sẽ map thành VARCHAR(255). Đây có nghĩa là tối đa là 255 ký tự. Vậy nếu field đó không quá 255 ký tự, bạn nên dùng kiểu string như username, name, email, ....
  • text: đối với nhũng field dài (lớn hơn 255 ký tự), bạn nên dùng text để đảm bảo không bị mất dữ liệu như content, description, comment, ...

Trong trường hợp bạn generate migration mà không có sẵn các method migration thì dưới đây là tóm tắt các migration methods.

add_column :table, :col_name, :type // thêm column
add_index :table, :column // thêm index cho column
change_column :table, :column, :type // thay đổi kiểu dữ liệu cho column
change_table :table { block } // thay đổi table
create_table :table_name { block } // tạo table mới
drop_table :table_name { block } // xóa table
remove_column :table, :column // xóa column
remove_index :table, :column // xóa index
rename_column :table, :col_name, :new // đổi tên column

Bạn có thể tham khảo CheatSheet về Rails migration tại đây: Rails migration CheatSheet

http://edgeguides.rubyonrails.org/active_record_migrations.html

https://medium.com/into-the-forest/rails-migrations-tricks-guide-code-cheatsheet-included-dca935354f22

0