ActiveStorageで画像アップロード機能を実装する方法・その他ポイント
ActiveStorageでの画像アップロードには「1枚画像のアップロード」と「複数画像のアップロード」の2種類が可能である。
ActiveStorageは関連づけたいモデルに「has_one_attached」「has_many_attached」のどちらかをつけると使えるようになる。
has_one_attached :image #imageは単数系になる
has_many_attached :images #imageは複数形になる
今回は
has_one_attached :favicon
has_one_attached :og_image
has_many_attached :main_images #複数形にする
とする。
ビューではそれぞれが画像を添付できるようにコードを書く
= f.input :favicon, as: :file, hint: 'PNG (32x32)'
- if @site.favicon.attached?
= image_tag @site.favicon_url('32x32')
br
br
= link_to '削除', admin_site_attachment_path(@site.favicon.id),
method: :delete, class: 'btn btn-danger'
= f.input :og_image, as: :file, hint: 'JPEG/PNG (1200x630)'
- if @site.og_image.attached?
= image_tag @site.og_image_url(:ogp), class: 'img-responsive'
br
br
= link_to '削除', admin_site_attachment_path(@site.og_image.id),
method: :delete, class: 'btn btn-danger'
= f.input :main_images, as: :file, input_html: { multiple: true }
- if @site.main_images.attached?
- @site.main_images.each do |main_image|
= image_tag url_for(main_image), class: 'img-responsive'
= link_to '削除', admin_site_attachment_path(main_image.id), method: :delete, class: 'btn btn-danger'
①simple_formで記述
②f.input :favicon, as: :file, hint: 'PNG (32x32)'と記述することでファイルを貼ることができるようになる。
③main_imagesにはmultiple: trueを記述し複数のファイルのアップロードを許可する。またmultiple: trueはsimple_formにはない機能なのでinput_htmlと記述することによって、multiple: trueの機能を使うことができる。
④admin_site_attachment_pathにそれぞれのidを使ってアクセスすることで削除の処理をadmin_site_attachment_pathに書くだけでまとめて処理ができるようになる
またsiteコントローラーにはmain_imageの値を入れれるように:favicon
:og_image
main_images: []
をそれぞれ記入
def site_params
params.require(:site).permit(:name, :subtitle, :description, :favicon, :og_image, main_images: [])
end
次に上記の④の処理をコントローラーに書いていく
before_action :set_site
def destroy
authorize(current_site) # current_siteはSite.firstで対応できるが、今後の拡張を考慮して権限管理する
ActiveStorage::Attachment.find(params[:id]).purge
@site.save
redirect_to edit_admin_site_path
end
private
def set_site
@site = Site.find(current_site.id)
end
ActiveStorage::Attachment.find(params[:id])
をすることによってfavicon
og_image
main_images
全ての中からidを取得するのでどの画像からの削除リクエストがきても対応できる
次にこのコントローラーのルーティングを書く
namespace :admin do
resource :site, only: %i[edit update] do
resources :attachments, only: %i[destroy], module: :site
end
end
admin配下にあるのでadminの内側、さらにsiteの配下にあるのでsiteの内側にかく