ユーザーidなどのIDが順番に取得されているので、
例えば下記のルートのように、 https://hogu.com/user/5 とか適当に手入力するとページ上からアクセスしなくても画面遷移してしまう。
Path / Url | HTTP | Path | Controller#Action |
---|---|---|---|
user_path | GET | /users/:id | users#show |
他のテーブルも同様で、例えばコメントの数や出品数など、どのくらいの数が登録されている等も推測できてしまい、個人的にも気持ち悪さがあったので乱数でidを登録する方法を調べながら行ったのでメモ。
class CreateUsers < ActiveRecord::Migration[5.1]
def change
create_table :users, id: false do |t|
t.string :id, limit: 36, null: false, primary_key: true
t.string :name, null: false
t.binary :avater
t.timestamps
end
end
end
今回idに入れたい乱数はUUIDになる。
既存のidのカラム型はintegerで格納できる文字数が少ないためstring型にする必要がある。
そのためcreate_table :users, id: false とした後に
t.string :id, limit: 36でカラム型を変えたidカラムを生成。
下記はモデルに使いたいUUID生成用のメソッド。
SecureRandom.uuidはrailsに既存であるメソッドになる。
rails cで確認すると下記のような結果になる。
[1] pry(main)> SecureRandom.uuid
=> "3f5ba6ef-ada9-43c8-b11c-b7d8f27c8d1f"
module IdGenerator
def self.included(uuid)
uuid.before_create :generate_uuid
end
def generate_uuid
self.id = loop do
uuid = SecureRandom.uuid
break uuid unless self.class.exists?(id: uuid)
end
end
end
モデルには上記のメソッドを使えるようにするためinclude IdGeneratorと記述。
私の場合は他のテーブルでもUUIDの乱数を生成したかったため、メソッドを切り分けしinclude IdGeneratorと記述するだけで他のモデル下でも使用できるようにした。
仮にUserモデルのみの場合はuser.rbに直接メソッドを記述してもOK。
class User < ApplicationRecord
include IdGenerator
(以下省略)
end
ここまで準備ができたら
rails db:drop、 rails db:create、 rails db:migrateを行う。
(私は始めからやり直しましたがdbを消さなくてもマイグレーションファイルのカラム型変更でもOK)
ユーザーは下記のようにidに乱数が入っている。
pry(main)> @user=User.all
#<User id: "ae6cdc44-68cd-4c76-b972-26d8a39b4bbb", name: "ユーザー1", avater: "8fe81aa7-9dbd-401d-b83c-86afe728aecd.png", created_at: "2019-05-05 03:40:36", updated_at: "2019-05-05 03:40:36", email: "a@test.com">,
#<User id: "d8d39f5e-ef4b-407b-ba23-8e4bbb83da12", name: "ユーザー2", avater: "90024ca8-f2ef-4796-ac19-e2e7adf5a2e3.png", created_at: "2019-05-05 03:40:36", updated_at: "2019-05-05 03:40:36", email: "b@test.com">,
上記のURLが無事下記のように推測不能なURLとなった。
http://localhost:3000/user/1
⬇︎
http://localhost:3000/user/ae6cdc44-68cd-4c76-b972-26d8a39b4bbb