Railsのidにuuidを使う方法(mysql2の場合)

##そもそもuuidとは
UUIDとはUniversally Unique Identifierの略。
普遍的にユニークなIDということです。
誰でも作れて世界中で被らないたった一つのIDと言えます。
こんな感じです→例：550e8400-e29b-41d4-a716-446655440000

##なぜuuidを使うのか
・IDから情報を推測しずらくなる。IDから情報を調べられて、サービスにどのくらいユーザーや投稿数などがあるのかを予測される心配が無くなります。
・データ情報がいくら増えようと値が限界を迎えることがなくなる。（mysqlでのデフォルトのidタイプであるbigintは、9223372036854775807までと値が決まっている)

##idにuuidを使う方法
###idのデータ形式を変更
デフォルトではidという名前を持つintegerのカラムをテーブルの主キーとして使用しています。

```
+------------+--------------+------+-----+---------+----------------+
| Field      | Type         | Null | Key | Default | Extra          |
+------------+--------------+------+-----+---------+----------------+
| id         | bigint(20)   | NO   | PRI | NULL    | auto_increment |
| name       | varchar(255) | YES  |     | NULL    |                |
| age        | int(11)      | YES  |     | NULL    |                |
| created_at | datetime     | NO   |     | NULL    |                |
| updated_at | datetime     | NO   |     | NULL    |                |
+------------+--------------+------+-----+---------+----------------+
```

これをstring型（文字列)にタイプを変更します。

```command:command
rails g migration ChangeColumnToUser（テーブル名)
```

```ruby:20190210010422_change_column_to_user.rb
class ChangeColumnToUser < ActiveRecord::Migration[5.2]
# 変更内容
  def up
    change_column :users, :id, :string
  end

  # 変更前の状態
  def down
    change_column :users, :id, :integer
  end
end
```
up・downメソッドでrollback（前のバージョンに戻す)できるようにします。

```command:command
rails db:migrate
```

```
+------------+--------------+------+-----+---------+-------+
| Field      | Type         | Null | Key | Default | Extra |
+------------+--------------+------+-----+---------+-------+
| id         | varchar(255) | NO   | PRI | NULL    |       |
| name       | varchar(255) | YES  |     | NULL    |       |
| age        | int(11)      | YES  |     | NULL    |       |
| created_at | datetime     | NO   |     | NULL    |       |
| updated_at | datetime     | NO   |     | NULL    |       |
+------------+--------------+------+-----+---------+-------+
```
これでidのタイプを変更することが出来ました。

##モデルにuuidを実装
以下のような処理を入れて,実現します。

```ruby:models/user.rb
class User < ApplicationRecord
  before_create :generate_token

  def generate_token
    self.id = loop do
      random_token = SecureRandom.uuid
      break random_token unless self.class.exists?(id: random_token)
    end
  end
end
```
参考:[railsでモデルにuuidを持たせる実装について - スタック・オーバーフロー](https://ja.stackoverflow.com/questions/37075/rails%E3%81%A7%E3%83%A2%E3%83%87%E3%83%AB%E3%81%ABuuid%E3%82%92%E6%8C%81%E3%81%9F%E3%81%9B%E3%82%8B%E5%AE%9F%E8%A3%85%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6)

##結果
これで試しに投稿してみると、下記の通りidにuuidを使うことができるようになっています。

```
+--------------------------------------+--------+------+---------------------+---------------------+
| id                                   | name   | age  | created_at          | updated_at          |
+--------------------------------------+--------+------+---------------------+---------------------+
| 9d5d5b70-4062-4253-99c5-e28998bcff13 | 太郎   |   20 | 2019-02-10 01:25:32 | 2019-02-10 01:25:32 |
+--------------------------------------+--------+------+---------------------+---------------------+
```

もちろん他にもいろんな方法があると思いますので、こっちの方が良いなどあれば教えてください！