Rails初学者がUUIDを導入して学んだこと
Rails初学者がUUIDを導入して学んだこと
はじめに
現在、未経験からWebエンジニアを目指してRuby on Railsを学習しています。
ポートフォリオとして開発しているコーデ記録アプリ「Stylog」で、投稿URLにUUIDを導入しました。
最初は、
「なぜUUIDを使うの?」
という状態でしたが、実際に導入してみると、
- 公開URLの安全性
- Railsのルーティング
to_param
など、多くの学びがありました。
この記事では、自分がUUIDを導入して理解したことをまとめます。
UUIDとは?
UUID(Universally Unique Identifier)は、世界中で重複しないことを目的とした識別子です。
例えば、通常のIDだと
/posts/1
/posts/2
/posts/3
ですが、UUIDだと
/posts/550e8400-e29b-41d4-a716-446655440000
のようになります。
なぜUUIDを導入したのか
最初は普通にidを使っていました。
/posts/1
/posts/2
/posts/3
しかしこれだと、
- 件数を推測できる
- 存在するURLを予測できる
という問題があります。
そこで、公開用IDとしてUUIDを利用することにしました。
実装方法
まずpostsテーブルにuuidカラムを追加しました。
add_column :posts, :uuid, :string
add_index :posts, :uuid, unique: true
モデルでは、
before_create :set_uuid
def to_param
uuid
end
private
def set_uuid
self.uuid ||= SecureRandom.uuid
end
を設定しました。
to_paramとは?
最初はこれがよく分かりませんでした。
Railsは通常、
post_path(post)
を書くと、
/posts/1
を生成します。
しかし、
def to_param
uuid
end
を書くと、
/posts/550e8400-e29b-41d4-a716-446655440000
になります。
つまり、URLで利用する値を変更できる仕組みです。
ハマったこと①
URLはUUIDになったのに詳細画面が開かない
UUID導入後、URLは変わったのに投稿詳細ページが表示できなくなりました。
原因はコントローラでした。
変更前
@post = Post.find(params[:id])
変更後
@post = Post.find_by!(uuid: params[:uuid])
URLはUUIDなのに、DB検索はidで探していたためエラーになっていました。
UUIDを使う場合は、取得処理もUUIDに合わせて変更する必要があります。
ハマったこと②
Renderでuuidがnilのレコードが存在していた
途中でRender上でエラーが発生しました。
調べてみると、
uuid: nil
の投稿が存在していました。
原因はUUID導入前に作成されたレコードでした。
既存レコードにはUUIDが設定されていなかったため、
No route matches
のようなエラーが発生していました。
既存レコードにもUUIDを付与することで解決しました。
UUIDを導入して良かったこと
導入前は、
「なぜわざわざUUIDを使うのだろう?」
と思っていました。
しかし実装してみると、
- URLから件数を推測されにくい
- 公開用IDと内部IDを分離できる
- 実務でも使われる設計を学べた
というメリットがありました。
学んだこと
UUID導入を通じて、単にURLを変更するだけではなく、
- Railsのルーティング
to_param-
findとfind_by! - データ移行
など多くのことを学べました。
特に、
def to_param
uuid
end
の仕組みを理解できたのは大きな収穫でした。
まとめ
最初は「なんとなくセキュリティのために使うもの」という認識でしたが、実際に導入してみるとRailsの仕組みそのものを理解する良い学習になりました。
もしRailsでポートフォリオを作っている方がいたら、UUIDの導入に挑戦してみるのもおすすめです。
実装だけでなく、
- URL生成
- レコード取得
- データ移行
まで考えるきっかけになると思います。
最後まで読んでいただきありがとうございました。
Discussion