Strong migration

1. Migration Hầu như tất cả Rails developer đều quen thuộc và sử dụng active record migrations để modify database. Với rails generator, bạn có thể tạo ra migration file với chỉ 1 command duy nhất Ví dụ để tạo table mới trong database. rails generate migration CreateProducts name:string# db/migrate/20210721140838_create_products.rbclassCreateProducts<ActiveRecord::Migration[6.0]defchange create_table :productsdo|t| t.string :nameendendend rails

1. Migration

  • Hầu như tất cả Rails developer đều quen thuộc và sử dụng active record migrations để modify database.
  • Với rails generator, bạn có thể tạo ra migration file với chỉ 1 command duy nhất
  • Ví dụ để tạo table mới trong database.
    rails generate migration CreateProducts name:string# db/migrate/20210721140838_create_products.rbclassCreateProducts<ActiveRecord::Migration[6.0]defchange
        create_table :productsdo|t|
          t.string :nameendendend
    
    rails db:migrate
  • Tương tự cho add_column, add_foreign_key, …. và các chức năng khác.
  • Nhanh, đơn giản, dễ sử dụng.
  • Tuy nhiên không phải tất cả migration được generate ra đều safe và good.
  • Gem strong_migrations được sử dụng để kiểm tra, phát hiện và ngăn các migraion này chạy.
  • Bạn có thể hiểu gem strong_migrations có tính năng như gem rubocop nhưng được dùng cho migration thay cho syntax, lint

2. Strong migration

a. Install

  • Thêm gem strong_migrations vào Gemile
    # Gemfile
    gem 'strong_migrations'
  • Chạy command để install gem strong_migrations
    bundle install

b. Config

  • Chạy command để generate ra file config cho gem strong_migrations
    rails generate strong_migrations:install
    
  • File config được gen ra có nội dung như sau
    # config/initializers/strong_migrations.rb# Mark existing migrations as safeStrongMigrations.start_after =20210721142403# Set timeouts for migrationsStrongMigrations.lock_timeout =10.seconds
    StrongMigrations.statement_timeout =1.hour
    
    # Analyze tables after indexes are added# Outdated statistics can sometimes hurt performanceStrongMigrations.auto_analyze =true# Set the version of the production database# so the right checks are run in development# StrongMigrations.target_version = 10# Add custom checks# StrongMigrations.add_check do |method, args|#   if method == :add_index && args[0].to_s == "users"#     stop! "No more indexes on the users table"#   end# end
  • Các config như StrongMigrations.start_after, StrongMigrations.lock_timeout được sử dụng để config gem strong_migrations

c. How it works

  • Các chức năng cơ bản của gem strong_migration bao gồm
  1. Phát hiện các migration unsafe
  2. Rails error và ngăn các migration unsafe được chạy
  3. Hiển thị hướng dẫn để làm migration safe hơn
  • Tất cả các chức năng này được thực hiện khi bạn chạy command rails db:migrate các migration được khởi tạo sao StrongMigrations.start_after sẽ được check

3. Check

a. Removing a column

i. Bad

  • Migration được gen cho removing a column thường là
    classRemoveSomeColumnFromUsers<ActiveRecord::Migration[6.1]defchange
        remove_column :users,:some_columnendend
  • Sau khi migraion này được chạy, app vẫn query tới column bị remove thì sẽ bị lỗi và raise exception cho đễn khi app được reboot, nhận source code mới.

ii. Good

  • Sử dụng method ignored_columns để column cần remove trong model.
    classUser<ApplicationRecordself.ignored_columns =["some_column"]end
  • Với method này thì các getter, setter liên quan đến column sẽ raise exception, các query vào model sẽ không query vào column này.
  • Deploy code
  • Tạo migration để remove the column (sử dụng safety_assured block)
    classRemoveSomeColumnFromUsers<ActiveRecord::Migration[6.1]defchange
        safety_assured { remove_column :users,:some_column}endend
  • Deploy code và run migration

b. Adding a column with a default value

i. Bad

  • Migration được gen cho adding a column with a default value thường là
    classAddSomeColumnToUsers<ActiveRecord::Migration[6.1]defchange
        add_column :users,:some_column,:text, default:"default_value"endend
  • Khi migraion này được chạy sẽ rewrite lại toàn bộ table và lock table đến khi migration được chạy xong, các request từ app đến DB trong thời gian này sẽ bị timeout và raise exception

ii. Good

  • Tách thành 2 migration add_columnchange_column_default
    classAddSomeColumnToUsers<ActiveRecord::Migration[6.1]defup
        add_column :users,:some_column,:text
        change_column_default :users,:some_column,"default_value"enddefdown
        remove_column :users,:some_columnendend

c. Other checks

  • Gem strong_migrations còn cung cấp thêm các check khác như changing the type of a column, renaming a column, …
  • Bạn có thể tìm hiểu nhiều hơn ở README.md

Nguồn: viblo.asia

Bài viết liên quan

Mình đang dùng Google Domains để check tên miền hàng ngày

Từ khi thông báo dịch vụ Google Domains bỏ mác Beta, mình mới để ý và bắt đầ

Cách sử dụng SFTP (Giao thức truyền file qua SSH an toàn hơn)

SFTP là cách an toàn để truyền files giữa các máy tính, gữa máy local và web hostin

Hotlinking: Key Reasons to Avoid and Methods to Protect Your Site

Hotlinking might seem an easy way to acquire website assets, but in reality, it brings several disad

Sự Khác Nhau Giữa Domain và Hosting Là Gì?

Sự khác nhau giữa domain và hosting là gì? Bài này giải thích ngắn và dễ hiểu nh