※2022年から技術系の記事は個人ブログに投稿しております。ぜひこちらもご覧ください→yamaday0u Blog
Ruby on Railsで画像投稿機能を実装する方法はたくさんあると思います。
この記事では未経験からのエンジニア転職を目指しているプログラミング初学者である私が、おそらく最も一般的な手法と思われるActive Storageを用いた実装方法をまとめました。
#Active StorageとImageMagick
今回の画像投稿機能は、画像をアップロードする機能と、画像を加工(サイズを変更したり保存形式を変更したり)する機能があります。
前者はActive Storageを、後者はImageMagickを使って実装します。
Active Storageとは
Rails5.2で追加された、ファイルアップロード機能を簡単に実装できるgemです。
元々はインストールが必要なgemでしたが、Railsに統合されたそうです。
ImageMagickとは
コマンドラインから画像の処理を加えることができるソフトウェアです。
このソフトウェアをRailsで使用するためにMiniMagickというgemを導入します。
またImageProcessingというgemを導入することで画像サイズを調整する機能も実装できます。
gem | 機能 |
---|---|
MiniMagick | ImageMagickの機能をRailsで扱えるようにする |
ImageProcessing | MiniMagickでは提供できない、画像サイズを調整する機能を提供する |
いくつか紹介しましたが、今回の記事ではActive Storageのみを扱います。
MiniMagickやImageProcessingは、今後この記事に追記するか別の記事にするかでまとめたいと思います。
Active Storageの使用準備
ターミナル上で画像投稿機能を実装したいアプリのディレクトリに移動し、下記のコマンドを入力します。
rails active_storage:install
rails db:migrate
rails active_storage:install
でActive Storageがインストールされ、マイグレーションファイルも生成されるので、rails db:migrate
でマイグレートしています。
このマイグレートによって、active_storage_blobs
とactive_storage_attachments
という名前のテーブルが2つ生成されます。これらのテーブルについて説明している分かりやすい記事があったので引用します。
これらのテーブルはBlobとAttachmentの2つのモデルが使います。Blobはファイル名、ファイルの種類、バイト数、誤り検出符号などのメタデータを保持するモデルで、Attachmentモデルは、BlobオブジェクトとActive Recordオブジェクトを紐付けるための中間テーブルです。なお、Active Storageを使う際、直接BlobとAttachmentモデルに触れる必要はありません。
Qiita【Rails 5.2】 Active Storageの使い方より
ちなみにrails active_storage:install
で生成されるマイグレーションファイルは次のようなものです。
class CreateActiveStorageTables < ActiveRecord::Migration[5.2]
def change
create_table :active_storage_blobs do |t|
t.string :key, null: false
t.string :filename, null: false
t.string :content_type
t.text :metadata
t.bigint :byte_size, null: false
t.string :checksum, null: false
t.datetime :created_at, null: false
t.index [ :key ], unique: true
end
create_table :active_storage_attachments do |t|
t.string :name, null: false
t.references :record, null: false, polymorphic: true, index: false
t.references :blob, null: false
t.datetime :created_at, null: false
t.index [ :record_type, :record_id, :name, :blob_id ], name: "index_active_storage_attachments_uniqueness", unique: true
t.foreign_key :active_storage_blobs, column: :blob_id
end
end
end
active_storage_blobs
とactive_storage_attachments
テーブルが作成されているのが分かります。
画像を保存できるようにする
先ほど作成したActive Storageのテーブルに、画像を保存するための実装を行います。
行うことは以下の2つです。
ここでは仮に、画像を保存したいテーブルをPostsテーブル(モデルがpost.rb)、コントローラーをposts_controller.rbとします。
- Active StorageのテーブルとPostsテーブルのアソシエーションを定義
- posts_controller.rbにて、imageカラムの保存を許可
これらを順番に実装します。
1. Active StorageのテーブルとPostsテーブルのアソシエーションを定義
アソシエーションの定義にはhas_one_attachedメソッド
を使います。
メソッド名 | 機能 |
---|---|
has_one_attached | 各レコードとファイルを1対1の関係で紐づける。has_one_attachedメソッドを記述したモデルの各レコードは、それぞれ1つのファイルを添付できる。 |
has_one_attachedメソッドをpost.rbに以下のように記述します。
class Post < ApplicationRecord
has_one_attached :image
end
:image
の部分はファイル名を表し、:photoなど他のファイル名にしても構いません。
この記述により、モデル.ファイル名
で、添付されたファイルにアクセスできるようになります(例:Post.image)。
さらに、このファイル名は、そのモデルが紐づいたフォームから送られるパラメーターのキーにもなります。
2. posts_controller.rbにて、imageカラムの保存を許可
以下のように記述します。
class PostsController < ApplicationController
def new
@post = Post.new
end
def create
@post = Post.create(post_params)
redirect_to root_path
end
priveate
def post_params
params.require(:post).permit(:image)
end
end
privateメソッドのpost_params
で、premitを使って:imageキー
の保存を許可しています。
ちなみに投稿ページは以下のように記述します。
<%= form_with model: @post, local: true do |form| %>
<%= form.file_field :image %>
<%= form.submit %>
<% end %>
以上で画像投稿機能の実装が完了しました。
この後の工程として、投稿した画像を表示する機能の実装がありますが、今回は割愛します。
参考資料
Railsガイド v6.0 Active Storageの概要
ImageMagick公式サイト
MiniMagick公式GitHub
ImageProcessing公式GitHub
Qiita【Rails 5.2】 Active Storageの使い方