やりたいこと
ActiveStorageを使い、Railsアプリに画像をアップロードする機能をつけたい(development環境)。
環境
試作アプリをつくる
active_storageというRailsアプリを作る。 続いて、簡単なブログ機能を作成し、マイグレーションも実行する。
rails new active_storage cd active_storage bin/rails g scaffold blog title:string memo:text bin/rails db:migrate
サーバーを起動し、表示されるか確認する。
bin/rails s
以下にアクセス。
簡易的なブログができた。
次に、ActiveStorageを使ってブログ記事に画像を投稿できるようにしてみる。
ActiveStorage
Rails5.2以降でActiveStorageは標準装備になった。 あらたにgemをインストールする必要はなく、以下のコマンドでRailsアプリ内で使えるようにしてあげればよい。
bin/rails active_storage:install Copied migration 20200227002536_create_active_storage_tables.active_storage.rb from active_storage
とあるマイグレーションファイルが作成された。
マイグレーションを実行すると、active_storage_blobsとactive_storage_attachmentsという名前の2つのテーブルが作られる。
- active_storage_blobs
- 添付されたファイルに対応するモデル
- ファイル名やメタデータ、サイズなどを管理
- active_storage_attachments
- active_storage_blobsとアプリ内の他のモデルを関連付ける中間テーブル
たとえば、blogsテーブルに画像を保存したい場合、active_storage_attachmentsを介して、active_storage_blobsと関連づく。
マイグレーションを実行。
bin/rails db:migrate
設定
アップロードした画像ファイルの保管についての設定をするため、次の2ステップをおこなう。
Rails.application.config.active_storage.service
にファイルを管理する場所の名前を設定する- ファイルの管理先の名前を
config/storage.yml
に定義する
development環境の場合、デフォルトのまま何も変える必要はない。
config/environments/development.rb
# Store uploaded files on the local file system (see config/storage.yml for options). config.active_storage.service = :local
config.active_storage.service
にはlocalが指定されている。
config/storage.yml
test: service: Disk root: <%= Rails.root.join("tmp/storage") %> local: service: Disk root: <%= Rails.root.join("storage") %> # Use rails credentials:edit to set the AWS secrets (as aws:access_key_id|secret_access_key) ~ ~
これでstorageディレクトリに画像が保存されるということになる。
モデルを修正
Blogモデルに以下を追記。
app/models/blog.rb
class Blog < ApplicationRecord has_one_attached :image end
これで、Blogモデルからimage
で画像を参照できる。
ストロングパラメーターを修正
画像を保存できるようにはなったが、これだとストロングパラメーターに引っかかるため、画像も通るようにする。
app/controllers/blogs_controller.rbに、:image
を追記。
~ ~ private ~ ~ # Only allow a list of trusted parameters through. def blog_params params.require(:blog).permit(:title, :memo, :image) end
ビューを修正
formやshowファイルなどにimageを登録、表示させる記述をする。
app/views/blogs/_form.html.erb
~ ~ <div class="field"> <%= form.label :memo %> <%= form.text_area :memo %> </div> # 追記 <div class="field"> <%= form.label :image %> <%= form.file_field :image %> </div> ~ ~
app/views/blogs/show.html.erb
<p> <strong>Image:</strong> <%= image_tag(@blog.image) if @blog.image.present? %> </p>
画像を表示したいのでimage_tag
ヘルパーを使う。
if @blog.image.present?
で「もし記事に画像があれば表示してよね」とRailsに指示している。
サーバーを起動
サーバーを起動し、画像をアップロードしてみる。 画像が添付できるようになっている。
適当に記事を作り、画像をアップすると、
画像が表示された!