LoginSignup
5
2

More than 3 years have passed since last update.

rails学習 ActiveStorage

Posted at

ActiveStorageで画像アップロード機能を実装する方法・その他ポイント

ActiveStorageでの画像アップロードには「1枚画像のアップロード」と「複数画像のアップロード」の2種類が可能である。
ActiveStorageは関連づけたいモデルに「has_one_attached」「has_many_attached」のどちらかをつけると使えるようになる。

has_one_attached :image     #imageは単数系になる
has_many_attached :images   #imageは複数形になる

今回は

site.rb
has_one_attached :favicon
has_one_attached :og_image
has_many_attached :main_images  #複数形にする

とする。

ビューではそれぞれが画像を添付できるようにコードを書く

edit.html.slim
= 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: [] をそれぞれ記入

site_controller.rb
def site_params
  params.require(:site).permit(:name, :subtitle, :description, :favicon, :og_image, main_images: [])
end

次に上記の④の処理をコントローラーに書いていく

AdminSiteAttachmentsController
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を取得するのでどの画像からの削除リクエストがきても対応できる

次にこのコントローラーのルーティングを書く

routes.rb
namespace :admin do
  resource :site, only: %i[edit update] do
    resources :attachments, only: %i[destroy], module: :site
  end
end

admin配下にあるのでadminの内側、さらにsiteの配下にあるのでsiteの内側にかく

5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2