セットアップ
% rails active_storage:install Copied migration 20240327082510_create_active_storage_tables.active_storage.rb from active_storage
% rails db:migrate == 20240327082510 CreateActiveStorageTables: migrating ======================== -- create_table(:active_storage_blobs, {:id=>:primary_key}) -> 0.0065s -- create_table(:active_storage_attachments, {:id=>:primary_key}) -> 0.0037s -- create_table(:active_storage_variant_records, {:id=>:primary_key}) -> 0.0020s == 20240327082510 CreateActiveStorageTables: migrated (0.0126s) ===============
Active Storageが利用する3つのテーブルが作成される。
Active Storageのサービスはconfig/storage.yml
で宣言する。
ローカルDiskサービスをdevelopment環境(開発環境)で使うには、config/environments/development.rb
に以下を記述。
(デフォルトはこの設定なので変更する必要なし)
config.active_storage.service = :local #ファイルをローカルに保存する。
上記の:local
はconfig/storage.yml
内のlocal:
の箇所。
local: service: Disk root: <%= Rails.root.join("storage") %> test: service: Disk root: <%= Rails.root.join("tmp/storage") %> amazon: service: S3 access_key_id: "" secret_access_key: "" bucket: "" region: "" # 例: 'ap-northeast-1'
amazon s3を使用するのであれば、:amazon
とする。
ファイルをレコードに添付する
has_one_attached
レコードとファイルの間に1対1のマッピングを設定します。レコード1件ごとに1個のファイルを添付できる。
今回wantモデルに一件の画像を追加したいので、app/models/want.rb
にhas_one_attached :image
を追記。
class Want < ApplicationRecord belongs_to :category belongs_to :user has_one_attached :image end
*もしまだモデルを作成していない場合は、$ rails generate model Want image:attachment
を実行。
(今回は既にモデルが作成されているので直接app/models/want.rb
にhas_one_attached :image
を追記)
<%= form.file_field :image %>
で書くことで画像付きのwantを作成できます。
<%= form_with url: wants_path, model: @wants do |form| %> <select name="category" > <% @categories.each do |category| %> <option value= <%= category.id %> ><%= category.name %></option> <% end %> </select> <%= form.file_field :image %> <div><%= form.label :商品名 %> <%= form.text_field :name %></div> <div><%= form.label :金額 %> <%= form.text_field :money %></div> <div><%= form.submit "新規登録" %></div> <% end %>
app/controllers/wants.controller.rb
のprivate
のwant_params
に:image
を追加。
private def want_params params.require(:want).permit(:name, :money, :category_id, :image) end
app/controllers/wants_controller.rb
をWant.create!
を変数に入れ、want.image.attach(params[:image])
を追記。
def create want = Want.create!( name: params[:name], money: params[:money], user_id: current_user.id, category_id: params[:category] ) want.image.attach(params[:image]) redirect_to "/wants" end
scheema.rbを削除しrails db:reset
→rails db:migrate
。
その後画像をアップロードし% tree storage
で画像が保存されているか確認。
% tree storage storage ├── m7 │ └── hy │ └── m7hyoyzztbvzqu5ndqitbbzqqh66 ├── py │ └── 15 │ └── py15yatuw28y0o7yrrkliedqyi62 └── zf └── 4l └── zf4ll26t6asw1t6bz5lq91argxdn 7 directories, 3 files
rails db
でselect * from active_storage_attachments;
とselect * from active_storage_blobs;
を確認。
$ tree storage
でフォルダに格納されているか確認。
ファイルを表示する
ファイルを表示する方法は2種類ある。
1. リダイレクトモード(※今回はこちらで実行する)
2. プロキシモード
リダイレクトモード
表示したいerbファイルに以下のいずれかを記述することで表示可能。
# どちらでも良い <img src="<%= url_for(want.image) %>" > <%= image_tag url_for(want.image) %>
画像のリサイズ
image_processingのgemをインストールする
Gemfileのgem "image_processing", "~> 1.2"
のコメントアウトを外し、$ bundle install
でインストール。
表示したいviewファイルを編集(今回はmy-page.html.erb)
<%= image_tag want.image.variant(resize_to_limit: [100, 100])%>
& brew vips
でvips
をインストール