Rails6 のちょい足しな新機能を試す67（text size 編）

# はじめに

Rails 6 に追加されそうな新機能を試す第67段。 今回は、 `text size` 編です。
Rails 6 では、 ActiveRecord のマイグレーションファイルの `text` に `:size` オプションを指定できるようになりました。

Ruby 2.6.3, Rails 6.0.0.rc1, MySQL 8.0.16, PostgreSQL 10.7 で確認しました。Rails 6.0.0.rc1 は `gem install rails --prerelease` でインストールできます。

（Rails 6.0.0 がリリースされましたが、 確認当時は、 Rails 6.0.0.rc1 が最新でした。悪しからず :bow: ）

```shell
$ rails --version
Rails 6.0.0.rc1
```

なんとなく手抜きで、 モデルを１つ作って確認してみます。

# プロジェクトを作る

```shell
rails new rails6_0_0rc1
cd rails6_0_0rc1
```

# model を作る

User モデルを作ります。

```shell
bin/rails g model User name
```

# マイグレーションファイルを編集する

users テーブルの マイグレーションファイルに text 型のカラムを追加します。

```ruby:db/migrate/20190726231951_create_users.rb
class CreateUsers < ActiveRecord::Migration[6.0]
  def change
    create_table :users do |t|
      t.string :name
      t.text :profile0
      t.text :profile1, limit: 255
      t.text :profile2, limit: 16777215
      t.text :profile3, limit: 4294967295
      t.text :profile4, size: :tiny
      t.text :profile5, size: :medium
      t.text :profile6, size: :long

      t.timestamps
    end
  end
end
```

# MySQLを使ってマイグレーションを実行する

データベースに MySQLを使い、マイグレーションを実行します。

```shell
$ bin/rails db:create db:migrate
```

# schema.rb を確認する

schema.rb では、以下のようになります。

```ruby:db/schema.rb
  create_table "users", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci", force: :cascade do |t|
    t.string "name"
    t.text "profile0"
    t.text "profile1", size: :tiny
    t.text "profile2", size: :medium
    t.text "profile3", size: :long
    t.text "profile4", size: :tiny
    t.text "profile5", size: :medium
    t.text "profile6", size: :long
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
  end
```

# mysql で確認する

`mysql` で確認すると以下のようになっていました。

```
mysql> show create table users\G
*************************** 1. row ***************************
       Table: users
Create Table: CREATE TABLE `users` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `profile0` text,
  `profile1` tinytext,
  `profile2` mediumtext,
  `profile3` longtext,
  `profile4` tinytext,
  `profile5` mediumtext,
  `profile6` longtext,
  `created_at` datetime(6) NOT NULL,
  `updated_at` datetime(6) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci |
```

# PostgreSQL では

`limit: 4294967295` を指定するとエラーになります。

```
ArgumentError: No text type has byte size 4294967295. The limit on text can be at most 1GB - 1byte.
```

ということで、以下のように修正して

```ruby:db/migrate/20190726231951_create_users.rb
class CreateUsers < ActiveRecord::Migration[6.0]
  def change
    create_table :users do |t|
      t.string :name
      t.text :profile0
      t.text :profile1, limit: 255
      t.text :profile2, limit: 16777215
      t.text :profile3 # , limit: 4294967295
      t.text :profile4, size: :tiny
      t.text :profile5, size: :medium
      t.text :profile6, size: :long

      t.timestamps
    end
  end
end
```

試してみると `schema.rb` は以下のようになります。

```ruby:db/schema.rb
  ...
  create_table "users", force: :cascade do |t|
    t.string "name"
    t.text "profile0"
    t.text "profile1"
    t.text "profile2"
    t.text "profile3"
    t.text "profile4"
    t.text "profile5"
    t.text "profile6"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
  end
  ...
```

# 試したソース

試したソースは以下にあります。
https://github.com/suketa/rails6_0_0rc1/tree/try067_text_size


# 参考情報

* [What is new in Rails 6.0](https://bogdanvlviv.com/posts/ruby/rails/what-is-new-in-rails-6_0.html)
* [MySQL: Support `:size` option to change text and blob size](https://github.com/rails/rails/pull/35071)