[Rails]ActiveStorageでファイルダウンロードするAPIを作る[S3]


やること

バックエンドでRailsを使用した場合に、URLを叩いてファイルをダウンロード出来るようにします。

前提

ActiveStorageでファイルをアップロードしていると仮定しています。保存先は(S3 or minio 使用)

実装

ルーティング

今回は、/upload_files/:id/downloadとなるようにルーティングを設定します。

resources :upload_files do
  member do
    get :download
  end
end

コントローラ

 def download
    upload_file = UploadFile.find(params[:id])

    file = upload_file.file.blob.download  # ダウンロードする

    if send_data(file, disposition: 'attachment',  # ダウンロードしたファイルを送信する
      filename: upload_file.file.blob.filename.to_s, # ファイル名の取得
      type: upload_file.file.blob.content_type) # content_typeの取得
      head :no_content # 送信出来たら、no_contentを返す
    else
      render json: upload_file.errors, status: :not_found  # エラーを返す
    end
  end

file = upload_file.file.blob.downloadとすることで、実際にファイルをActiveStorageからダウンロードすることが出来ます。

上記のやり方がなかなか見つからず困っていたのですが、ActiveStorageの公式ドキュメントに書いてありました!
やはり困ったら公式が一番ですね。
https://railsguides.jp/active_storage_overview.html

他にもupload_file.file.blob.filename.to_sとすることで、ファイル名を動的に取得しています。
これによって、ファイル名に正しく拡張子が含まれます。

感想

困ったら公式を読むことが大事だと実感しました!