<commit_before>**DO NOT READ THIS FILE ON GITHUB, GUIDES ARE PUBLISHED ON http://guides.rubyonrails.org.**

Active Record マイグレーション
========================

マイグレーション (migration) はActive Recordの機能の1つであり、データベーススキーマを長期にわたって安定して発展・増築し続けることができるようにするための仕組みです。マイグレーション機能のおかげで、Rubyで作成されたマイグレーション用のDSL (ドメイン固有言語) を用いて、テーブルの変更を簡単に記述できます。スキーマを変更するためにSQLを直に書いて実行する必要がありません。

このガイドの内容:

* マイグレーション作成で利用できるジェネレータ
* Active Recordが提供するデータベース操作用メソッド群の解説
* マイグレーション実行とスキーマ更新用の`rails`タスクの解説
* マイグレーションとスキーマファイル`schema.rb`の関係

--------------------------------------------------------------------------------

マイグレーションの概要
------------------

マイグレーションは、[データベーススキーマの継続的な変更](https://en.wikipedia.org/wiki/Schema_migration) (英語) を、統一的かつ簡単に行なうための便利な手法です。マイグレーションではRubyのDSLを使っているので、生のSQLを作成する必要がなく、スキーマとスキーマへの変更をデータベースの種類に依存せずに済みます。

1つ1つのマイグレーションは、データベースの新しい'version'とみなすことができます。スキーマは最初空の状態から始まり、マイグレーションによる変更が加わるたびにテーブル、カラム、エントリが追加または削除されます。Active Recordは時系列に沿ってスキーマを更新する方法を知っているので、履歴のどの時点からでも最新バージョンのスキーマに更新することができます。Active Recordは`db/schema.rb`ファイルを更新し、データベースの最新の構造と一致するようにします。

マイグレーションの例を以下に示します。

```ruby
class CreateProducts < ActiveRecord::Migration[5.0]
  def change
    create_table :products do |t|
      t.string :name
      t.text :description

      t.timestamps
    end
  end
end
```

上のマイグレーションを実行すると`products`という名前のテーブルが追加されます。この中には`name`というstringカラムと、`description`というtextカラムが含まれています。主キーは`id`という名前で暗黙に追加されます。`id`はActive Recordモデルにおけるデフォルトの主キーです。`timestamps`マクロは、`created_at`と`updated_at`という2つのカラムを追加します。これらの特殊なカラムが存在する場合、Active Recordによって自動的に管理されます。

マイグレーションは、時間を先に進めるときに実行したい動作を定義していることにご注目ください。マイグレーションの実行前にはテーブルは1つもありません。マイグレーションを実行すると、テーブルが作成されます。Active Recordは、このマイグレーションの進行を逆転させる方法も知っています。マイグレーションをロールバックすると、テーブルは削除されます。

スキーマ変更のステートメントを利用できるトランザクションがデータベースでサポートされている場合、マイグレーションはトランザクションの内側にラップされて実行されます。これらがデータベースでサポートされていない場合は、マイグレーション中に一部が失敗した場合にロールバックされません。その場合は、変更を手動でロールバックする必要があります。

NOTE: ある種のクエリは、トランザクション内で実行できないことがあります。アダプタがDDLトランザクションをサポートしている場合は、`disable_ddl_transaction!`を使えば単一のマイグレーションでこれらを無効にできます。

マイグレーションを逆方向に実行 (ロールバック) する方法が推測できない場合、`reversible` を使います。

```ruby
class ChangeProductsPrice < ActiveRecord::Migration[5.0]
  def change
    reversible do |dir|
      change_table :products do |t|
        dir.up   { t.change :price, :string }
        dir.down { t.change :price, :integer }
      end
    end
  end
end
```

`change`の代りに`up`と`down`を使うこともできます。

```ruby
class ChangeProductsPrice < ActiveRecord::Migration[5.0]
  def up
    change_table :products do |t|
      t.change :price, :string
    end
  end

  def down
    change_table :products do |t|
      t.change :price, :integer
    end
  end
end
```

マイグレーションを作成する
--------------------

### 単独のマイグレーションを作成する

マイグレーションは`db/migrate`ディレクトリに保存されます。1つのファイルが1つのマイグレーションクラスに対応します。マイグレーションファイル名は`YYYYMMDDHHMMSS_create_products.rb`のような形式になります。ファイル名の日時はマイグレーションを識別するUTCタイムスタンプであり、アンダースコアにつづいてマイグレーション名が記述されます。マイグレーション クラスの名前 (CamelCaseで表されるバージョン) は、ファイル名の後半と一致する必要があります。たとえば、`20080906120000_create_products.rb`では`CreateProducts`というクラスが定義され、`20080906120001_add_details_to_products.rb`では`AddDetailsToProducts`というクラスが定義される必要があります。Railsではマイグレーションの実行順序をファイル名のタイムスタンプで決定します。従って、マイグレーションを他のアプリケーションからコピーしたり、自分でマイグレーションを生成する場合は、実行順に注意する必要があります。

タイムスタンプを算出する作業は退屈です。Active Recordにはこれらを扱うためのジェネレータが用意されています。

```bash
$ rails generate migration AddPartNumberToProducts
```

これによって、適切な名前の付いた空のマイグレーションが作成されます。

```ruby
class AddPartNumberToProducts < ActiveRecord::Migration[5.0]
  def change
  end
end
```

このジェネレータでは、ファイル名の末尾にタイムスタンプを追加する以外の操作もできます。命名規約や追加の（オプション）引数に基づいて、マイグレーションに肉付けすることもできます。

マイグレーション名が"AddColumnToTable"や"RemoveColumnFromTable"で、かつその後ろにカラム名や型が続く形式になっていれば、適切な`add_column`文や`remove_column`文を含むマイグレーションが作成されます。

```bash
$ rails generate migration AddPartNumberToProducts part_number:string
```

上を実行すると以下が生成されます。

```ruby
class AddPartNumberToProducts < ActiveRecord::Migration[5.0]
  def change
    add_column :products, :part_number, :string
  end
end
```

新しいカラムにインデックスを追加したい場合は以下のようにします。

```bash
$ rails generate migration AddPartNumberToProducts part_number:string:index
```

上を実行すると以下が生成されます。

```ruby<commit_msg>Fix word<commit_after>**DO NOT READ THIS FILE ON GITHUB, GUIDES ARE PUBLISHED ON http://guides.rubyonrails.org.**

Active Record マイグレーション
========================

マイグレーション (migration) はActive Recordの機能の1つであり、データベーススキーマを長期にわたって安定して発展・増築し続けることができるようにするための仕組みです。マイグレーション機能のおかげで、Rubyで作成されたマイグレーション用のDSL (ドメイン固有言語) を用いて、テーブルの変更を簡単に記述できます。スキーマを変更するためにSQLを直に書いて実行する必要がありません。

このガイドの内容:

* マイグレーション作成で利用できるジェネレータ
* Active Recordが提供するデータベース操作用メソッド群の解説
* マイグレーション実行とスキーマ更新用の`rails`タスクの解説
* マイグレーションとスキーマファイル`schema.rb`の関係

--------------------------------------------------------------------------------

マイグレーションの概要
------------------

マイグレーションは、[データベーススキーマの継続的な変更](https://en.wikipedia.org/wiki/Schema_migration) (英語) を、統一的かつ簡単に行なうための便利な手法です。マイグレーションではRubyのDSLを使っているので、生のSQLを作成する必要がなく、スキーマとスキーマへの変更をデータベースの種類に依存せずに済みます。

1つ1つのマイグレーションは、データベースの新しい'version'とみなすことができます。スキーマは最初空の状態から始まり、マイグレーションによる変更が加わるたびにテーブル、カラム、エントリが追加または削除されます。Active Recordは時系列に沿ってスキーマを更新する方法を知っているので、履歴のどの時点からでも最新バージョンのスキーマに更新することができます。Active Recordは`db/schema.rb`ファイルを更新し、データベースの最新の構造と一致するようにします。

マイグレーションの例を以下に示します。

```ruby
class CreateProducts < ActiveRecord::Migration[5.0]
  def change
    create_table :products do |t|
      t.string :name
      t.text :description

      t.timestamps
    end
  end
end
```

上のマイグレーションを実行すると`products`という名前のテーブルが追加されます。この中には`name`というstringカラムと、`description`というtextカラムが含まれています。主キーは`id`という名前で暗黙に追加されます。`id`はActive Recordモデルにおけるデフォルトの主キーです。`timestamps`マクロは、`created_at`と`updated_at`という2つのカラムを追加します。これらの特殊なカラムが存在する場合、Active Recordによって自動的に管理されます。

マイグレーションは、時間を先に進めるときに実行したい動作を定義していることにご注目ください。マイグレーションの実行前にはテーブルは1つもありません。マイグレーションを実行すると、テーブルが作成されます。Active Recordは、このマイグレーションの進行を逆転させる方法も知っています。マイグレーションをロールバックすると、テーブルは削除されます。

スキーマ変更のステートメントを利用できるトランザクションがデータベースでサポートされている場合、マイグレーションはトランザクションの内側にラップされて実行されます。これらがデータベースでサポートされていない場合は、マイグレーション中に一部が失敗した場合にロールバックされません。その場合は、変更を手動でロールバックする必要があります。

NOTE: ある種のクエリは、トランザクション内で実行できないことがあります。アダプタがDDLトランザクションをサポートしている場合は、`disable_ddl_transaction!`を使えば単一のマイグレーションでこれらを無効にできます。

マイグレーションを逆方向に実行 (ロールバック) する方法が推測できない場合、`reversible` を使います。

```ruby
class ChangeProductsPrice < ActiveRecord::Migration[5.0]
  def change
    reversible do |dir|
      change_table :products do |t|
        dir.up   { t.change :price, :string }
        dir.down { t.change :price, :integer }
      end
    end
  end
end
```

`change`の代りに`up`と`down`を使うこともできます。

```ruby
class ChangeProductsPrice < ActiveRecord::Migration[5.0]
  def up
    change_table :products do |t|
      t.change :price, :string
    end
  end

  def down
    change_table :products do |t|
      t.change :price, :integer
    end
  end
end
```

マイグレーションを作成する
--------------------

### 単独のマイグレーションを作成する

マイグレーションは`db/migrate`ディレクトリに保存されます。1つのファイルが1つのマイグレーションクラスに対応します。マイグレーションファイル名は`YYYYMMDDHHMMSS_create_products.rb`のような形式になります。ファイル名の日時はマイグレーションを識別するUTCタイムスタンプであり、アンダースコアにつづいてマイグレーション名が記述されます。マイグレーション クラスの名前 (CamelCaseで表されるバージョン) は、ファイル名の後半と一致する必要があります。たとえば、`20080906120000_create_products.rb`では`CreateProducts`というクラスが定義され、`20080906120001_add_details_to_products.rb`では`AddDetailsToProducts`というクラスが定義される必要があります。Railsではマイグレーションの実行順序をファイル名のタイムスタンプで決定します。従って、マイグレーションを他のアプリケーションからコピーしたり、自分でマイグレーションを生成する場合は、実行順に注意する必要があります。

タイムスタンプを算出する作業は退屈です。Active Recordにはこれらを扱うためのジェネレータが用意されています。

```bash
$ rails generate migration AddPartNumberToProducts
```

これによって、適切な名前の付いた空のマイグレーションが作成されます。

```ruby
class AddPartNumberToProducts < ActiveRecord::Migration[5.0]
  def change
  end
end
```

このジェネレータでは、ファイル名の先頭にタイムスタンプを追加する以外の操作もできます。命名規約や追加の（オプション）引数に基づいて、マイグレーションに肉付けすることもできます。

マイグレーション名が"AddColumnToTable"や"RemoveColumnFromTable"で、かつその後ろにカラム名や型が続く形式になっていれば、適切な`add_column`文や`remove_column`文を含むマイグレーションが作成されます。

```bash
$ rails generate migration AddPartNumberToProducts part_number:string
```

上を実行すると以下が生成されます。

```ruby
class AddPartNumberToProducts < ActiveRecord::Migration[5.0]
  def change
    add_column :products, :part_number, :string
  end
end
```

新しいカラムにインデックスを追加したい場合は以下のようにします。

```bash
$ rails generate migration AddPartNumberToProducts part_number:string:index
```

上を実行すると以下が生成されます。

```ruby
{'fraction_non_alphanumeric': 0.11411117898594991, 'fraction_numerical': 0.010995723885155772, 'mean_word_length': 7.104950495049505, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 3, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3007586', 'n_tokens_mistral': 5504, 'n_tokens_neox': 5022, 'n_words': 340}