Skip to main content

rails-migrations

This skill should be used when the user asks about "migrations", "database schema", "create_table", "add_column", "remove_column", "add_index", "foreign keys", "db:migrate", "db:rollback", "schema.rb", "change_column", "reversible", "references", "timestamps", or needs guidance on modifying database structure in Rails applications.

الانتقال إلى التثبيت

معلومات المصدر

المستودع
bastos/ruby-plugin-marketplace
آخر نشاط في المصدر
٩ يناير ٢٠٢٦ في ٠٣:٠٥
لغة SKILL.md المكتشفة
الإنجليزية
النجوم
٣
التفرعات
٠

خيارات التثبيت

يُحدَّد Prompt الذي يراجع المصدر أولًا بشكل افتراضي. يمكنك التبديل إلى أمر مباشر أو تنزيل نسخة محلية.

مراجعة ملفات المصدر

اقرأ SKILL.md وأي ملفات مرافقة يعرضها SkillsMP قبل أن تقرر التثبيت.

مستكشف الملفات
2 ملفات

عرض SKILL.md

SKILL.md
تعليمات المصدر · معاينة للقراءة فقط
name
rails-migrations
description
This skill should be used when the user asks about "migrations", "database schema", "create_table", "add_column", "remove_column", "add_index", "foreign keys", "db:migrate", "db:rollback", "schema.rb", "change_column", "reversible", "references", "timestamps", or needs guidance on modifying database structure in Rails applications.
version
1.0.0
# ActiveRecord Migrations Comprehensive guide to creating and managing database migrations in Rails. ## Creating Migrations ### Generator Commands ```bash # Standalone migration rails generate migration AddPartNumberToProducts part_number:string # Create table rails generate migration CreateProducts name:string price:decimal # Add reference/foreign key rails generate migration AddUserRefToProducts user:references # Add index rails generate migration AddIndexToUsersEmail ``` ### Naming Conventions Migration names determine auto-generated code: | Pattern | Generated Code | |---------|----------------| | `AddColumnToTable` | `add_column :table, :column, :type` | | `RemoveColumnFromTable` | `remove_column :table, :column, :type` | | `CreateTable` | `create_table` block | | `AddIndexToTable` | `add_index :table, :column` | File format: `YYYYMMDDHHMMSS_migration_name.rb` ## Column Types | Type | Description | |------|-------------| | `:string` | Short text (VARCHAR, default 255) | | `:text` | Long text (unlimited) | | `:integer` | Standard integer | | `:bigint` | Large integer (default for PKs in Rails 5.1+) | | `:float` | Floating point | | `:decimal` | Precise decimal (use for money) | | `:boolean` | True/false | | `:date` | Date only | | `:time` | Time only | | `:datetime` | Date and time | | `:timestamp` | Same as datetime | | `:binary` | Binary data | | `:json` | JSON (native if supported) | | `:jsonb` | Binary JSON (PostgreSQL) | | `:uuid` | UUID type | | `:references` | Foreign key column | ## Column Modifiers ```ruby add_column :products, :name, :string, null: false, # NOT NULL constraint default: "Untitled", # Default value limit: 100, # Max length (string) or bytes (integer) precision: 8, # Total digits (decimal) scale: 2, # Digits after decimal index: true, # Create index unique: true, # Unique index comment: "Product name" # Database comment ``` ## Table Operations ### Create Table ```ruby class CreateProducts < ActiveRecord::Migration[7.1] def change create_table :products do |t| t.string :name, null: false t.text :description t.decimal :price, precision: 10, scale: 2 t.integer :quantity, default: 0 t.boolean :active, default: true t.references :category, foreign_key: true t.references :user, null: false, foreign_key: true t.timestamps # created_at and updated_at end add_index :products, :name add_index :products, [:category_id, :active] end end ``` ### Modify Table ```ruby class AddFieldsToProducts < ActiveRecord::Migration[7.1] def change change_table :products do |t| t.string :sku t.remove :temporary_field t.rename :old_name, :new_name t.index :sku, unique: true end end end ``` ### Drop Table ```ruby def change drop_table :products do |t| # Include schema for reversibility t.string :name t.timestamps end end ``` ## Column Operations ### Add Columns ```ruby def change add_column :products, :weight, :decimal, precision: 8, scale: 2 add_column :products, :dimensions, :json add_column :users, :role, :string, default: "member", null: false end ``` ### Remove Columns ```ruby def change # Include type for reversibility remove_column :products, :discontinued, :boolean, default: false end ``` ### Rename Column ```ruby def change rename_column :products, :upc, :sku end ``` ### Change Column ```ruby # Not automatically reversible - use up/down def up change_column :products, :price, :decimal, precision: 12, scale: 2 change_column_null :products, :name, false change_column_default :products, :status, from: nil, to: "draft" end def down change_column :products, :price, :decimal, precision: 10, scale: 2 change_column_null :products, :name, true change_column_default :products, :status, from: "draft", to: nil end ``` ## References and Foreign Keys ### Add Reference ```ruby def change # Adds category_id column with index and foreign key add_reference :products, :category, foreign_key: true # Polymorphic reference add_reference :comments, :commentable, polymorphic: true, index: true # Without foreign key constraint add_reference :products, :supplier, foreign_key: false # Nullable reference add_reference :products, :brand, null: true, foreign_key: true end ``` ### Foreign Key Options ```ruby def change add_foreign_key :articles, :authors # Custom column name add_foreign_key :articles, :users, column: :author_id # On delete behavior add_foreign_key :comments, :articles, on_delete: :cascade add_foreign_key :orders, :users, on_delete: :nullify # Remove foreign key remove_foreign_key :articles, :authors remove_foreign_key :articles, column: :author_id end ``` ## Indexes ```ruby def change # Basic index add_index :users, :email # Unique index add_index :users, :email, unique: true # Composite index add_index :products, [:category_id, :status] # Partial index (PostgreSQL) add_index :orders, :shipped_at, where: "shipped_at IS NOT NULL" # Named index add_index :products, :sku, name: "idx_products_sku" # Remove index remove_index :users, :email remove_index :products, name: "idx_products_sku" end ``` ## The change Method Auto-reversible operations (use `change`): - `add_column` / `remove_column` (with type) - `add_foreign_key` / `remove_foreign_key` - `add_index` / `remove_index` - `add_reference` / `remove_reference` - `add_timestamps` / `remove_timestamps` - `create_table` / `drop_table` (with block) - `create_join_table` / `drop_join_table` - `rename_column` - `rename_index` - `rename_table` - `change_column_default` (with `:from` and `:to`) - `change_column_null` ## Reversible and Up/Down ### Using reversible ```ruby def change create_table :products do |t| t.string :name t.timestamps end reversible do |dir| dir.up do execute <<-SQL CREATE INDEX idx_products_search ON products USING gin(to_tsvector('english', name)); SQL end dir.down do execute "DROP INDEX idx_products_search;" end end end ``` ### Using up/down ```ruby def up change_column :products, :price, :decimal, precision: 12, scale: 2 end def down change_column :products, :price, :decimal, precision: 10, scale: 2 end ``` ### Irreversible Migration ```ruby def up drop_table :legacy_products end def down raise ActiveRecord::IrreversibleMigration end ``` ## Running Migrations ```bash # Run pending migrations rails db:migrate # Migrate to specific version rails db:migrate VERSION=20240101120000 # Rollback last migration rails db:rollback # Rollback multiple migrations rails db:rollback STEP=3 # Redo last migration (rollback + migrate) rails db:migrate:redo # Check migration status rails db:migrate:status # Run in specific environment rails db:migrate RAILS_ENV=production ``` ## Database Commands ```bash # Create database rails db:create # Drop database rails db:drop # Reset (drop + create + migrate) rails db:reset # Setup (create + load schema + seed) rails db:setup # Prepare (idempotent setup) rails db:prepare # Load schema directly (faster than migrations) rails db:schema:load # Dump current schema rails db:schema:dump # Run seeds rails db:seed ``` ## Safe Migration Practices ### Do's 1. **Always include column type in remove_column** for reversibility 2. **Use `change_column_default` with `:from` and `:to`** 3. **Add indexes on foreign keys** (automatic with `references`) 4. **Test rollback**: `rails db:migrate:redo` 5. **Keep migrations small and focused** ### Don'ts 1. **Don't edit committed migrations** - create new ones 2. **Don't use model classes** directly in migrations (schema may change) 3. **Don't add data migrations** - use seeds or maintenance tasks ### Data Migration Alternative ```ruby # Instead of data in migrations, use: # lib/tasks/data_migration.rake namespace :data do desc "Migrate user status values" task migrate_status: :environment do User.where(status: "old_value").update_all(status: "new_value") end end ``` ### Concurrent Index (PostgreSQL) ```ruby class AddIndexToUsersEmail < ActiveRecord::Migration[7.1] disable_ddl_transaction! def change add_index :users, :email, algorithm: :concurrently end end ``` ## Additional Resources ### Reference Files - **`references/migration-patterns.md`** - Complex migration patterns, zero-downtime migrations
عرض على GitHub