Rails Active Storage完全入門|has_one_attached / has_many_attachedの使い分けと設計指針
生徒
「Railsで画像をアップロードしたいんですが、has_one_attachedとhas_many_attachedって何が違うんですか?」
先生
「どちらもActive Storageでファイルを扱うための仕組みですが、考え方はとてもシンプルですよ」
生徒
「プログラミング未経験でも理解できますか?」
先生
「もちろんです。写真アルバムを例にしながら、ゆっくり説明していきましょう」
1. RailsとActive Storageの基本的な考え方
Railsは、Webアプリケーションを効率よく作るためのフレームワークです。 その中でActive Storageは、画像やPDFなどのファイルを簡単にアップロード・保存・表示するための仕組みです。 ファイルはパソコンの中の写真のようなもので、データベースには直接保存せず、関連づけだけを管理します。
Active Storageを使うと、ローカル環境だけでなく、Amazon S3などのクラウドストレージにも同じ書き方で保存できるのが特徴です。 初心者の方は「Rails標準のファイル置き場」と考えると理解しやすいでしょう。
2. has_one_attachedとは?1つだけ添付する設計
has_one_attachedは、「1つのデータに対して、1つのファイルだけを持たせたい」ときに使います。
たとえば、ユーザーのプロフィール画像のように「基本的に1枚だけ」で十分な場合です。
これは「社員証に貼る顔写真」をイメージすると分かりやすいです。 社員1人につき、写真は1枚だけですよね。
class User < ApplicationRecord
has_one_attached :avatar
end
このように書くことで、Userモデルはavatarという名前の画像を1つだけ持てるようになります。
新しい画像をアップロードすると、古い画像は自動的に置き換えられます。
3. has_many_attachedとは?複数ファイルを扱う設計
has_many_attachedは、「1つのデータに対して、複数のファイルを持たせたい」ときに使います。
代表的な例は、商品に複数の写真を登録したい場合です。
これは「旅行のアルバム」を想像してください。 1つの旅行に対して、写真が何枚もありますよね。
class Product < ApplicationRecord
has_many_attached :images
end
この場合、1つの商品に対して何枚でも画像を追加できます。 削除や並び替えなども、配列のような感覚で扱えるのが特徴です。
4. 使い分けの基本ルール|迷ったときの判断基準
初心者が迷いやすいポイントですが、判断基準はとても単純です。
- 「基本的に1つだけ」→ has_one_attached
- 「複数登録したい可能性がある」→ has_many_attached
将来増えるかもしれないからと、何でもhas_many_attachedにするのはおすすめしません。
設計が複雑になり、ビューやフォームのコードも難しくなります。
まずは「現実世界で1つか複数か」を考えると、自然に答えが見えてきます。
5. フォームでの指定方法の違い
ファイルアップロードでは、フォームの書き方も少し変わります。
<%= form_with model: @user do |f| %>
<%= f.file_field :avatar %>
<%= f.submit "保存" %>
<% end %>
一方、複数ファイルの場合はmultipleを指定します。
<%= form_with model: @product do |f| %>
<%= f.file_field :images, multiple: true %>
<%= f.submit "登録" %>
<% end %>
この違いを理解しておくと、画面作成でつまずきにくくなります。
6. 設計ミスを防ぐための注意点
よくある失敗は、「後から1枚に戻したくなる」ケースです。
一度has_many_attachedで作ると、コードや画面が複数前提になります。
最初はシンプルに作り、必要になったら拡張する方が、Railsらしい開発スタイルです。 Active Storageは後から変更しにくいため、最初の設計がとても重要です。
7. データベースとActive Storageの関係
Active Storageでは、実際のファイル情報は専用のテーブルで管理されます。 アプリのモデルには「関連づけ」だけが保存されるため、データベース設計を意識しすぎる必要はありません。
初心者の方は「Railsが裏でよしなに管理してくれている」と考えて問題ありません。 その代わり、正しいマクロ(has_one_attached / has_many_attached)を選ぶことが重要になります。
8. 画像表示の基本イメージ
最後に、画像を表示する簡単な例を見ておきましょう。
<%= image_tag @user.avatar if @user.avatar.attached? %>
複数の場合は、繰り返し表示します。
<% @product.images.each do |image| %>
<%= image_tag image %>
<% end %>
このように、1つか複数かで書き方が変わる点も、使い分けの重要な理由です。