今まで、某スクールで学習を学んだときには、
「refile」を使うように教わっていました。
ですが、毎回事前に画像用のカラムを作成しなければいけなかったり、
また、複数アップロードができるようにするにはいくつか設定を加えてあげなければいけなかったりと面倒に感じていました。
そこで、調べていて見つけたのが「Active Storage」です。
カラムを事前に作る必要がなく、
インストールをして即使える。かつ、複数アップロードにも簡単に対応可能な優れものでした!
忘れないためにもメモしていきます〜。
1.Active Storageの導入
まずは、インストールをしていきます。
と言っても、以下のコマンドを実行させるだけです。
rails active_storage:install
rails db:migrate
Active Storageのインストールと、
その後にマイグレーションを行います。
2.Modelの設定
次は、追加したいモデルに設定をかけていきます。
「has_one_attached :名前」としてあげます。
ここでは、memberモデルにプロフィール用画像を設定するために、
「profile_image」という項目を作ることにします。
class Member < ApplicationRecord
# Active Storage
has_one_attached :profile_image
end
3.Controllerの設定
コントローラを設定してあげます。
カラムと同じ扱い方をすればいいので、
private
def member_params
params.require(:member).permit(:profile_image)
end
と言った具合に、「member_params」を作ってあげて、
「prams.require〜」すれば扱うことができます。
今回実際に構築した場合は、
「devise」で作成した「member」の中で
一緒に「profile_image」を扱いたかったので、以下のように設定しました。
class ApplicationController < ActionController::Base
before_action :configure_permitted_parameters , if: :devise_controller?
protected
def configure_permitted_parameters
# 登録時のカラム入力許可
devise_parameter_sanitizer.permit(:sign_up, keys: [
:last_name_kana,
:first_name_kana,
:last_name,
:first_name,
:member_status,
:profile_image
])
# 更新時のカラム入力許可
devise_parameter_sanitizer.permit(:account_update, keys: [
:last_name_kana,
:first_name_kana,
:last_name,
:first_name,
:member_status,
:profile_image
])
end
end
「devise」と合わせて使いたい方は参考にしていただければと思います。
3.Viewの設定
あとは、ビューに追加していくだけです。
「<%= f.file_field :profile_image %>」の部分が画像をアップロードするためのボタンになります。
<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f| %>
<%= render "members/shared/error_messages", resource: resource %>
<div class="form-row pb-3">
<div class="col-12">
<%= f.label :profile_image, "プロフィール画像", class:"" %>
</div>
<div class="col-12 text-center pb-2">
<%= render "members/profile_image", member: @member %>
</div>
<div class="col-12 text-center pb-3">
<%= f.file_field :profile_image, class:"btn btn-sm" %>
</div>
</div>
<!--- 省略 --->
<div class="actions pb-3">
<%= f.submit "アカウント情報を更新する", class:"btn btn-sg03 btn-block" %>
</div>
<% end %>
「<%= image_tag member.profile_image %>」の部分は、
アップロードされている画像を表示されている場所です。
<% if member.profile_image.attached? %>
<%= image_tag member.profile_image, class:"border border-secondary rounded-circle", size:"100x100" %>
<% else %>
画像なし
<% end %>
ここでは、「<% if member.profile_image.attached? %>」で
画像が既にアップロードされていれば image_tag を表示して、
されていなければ、「画像なし」と表示されるようになっており、
それぞれ分岐させています。
# 複数アップロードさせる場合
複数アップロードできるようにするには、
モデルを「has_many_attached :名前」にしてあげます。
class Post < ApplicationRecord
# Active Storage
has_many_attached :images
end
コントローラは、「images:[]」という書き方にして、
画像を配列で保存できるようにします。
def post_params
params.require(:post).permit(:postname, :description, :category_id, :member_id, images:[])
end
ビューは「<% @post.images.each do |image| %>」を使い、
繰り返しの記述をして、配列内にある画像全てを表示させるようにします。
もちろん、「<% if @post.images.attached? %>」も使い、
画像がある場合は、画像を表示させます。
ない場合には、「NO IMAGE」画像などを設定しておくといいかもしれませんね!
<% if @post.images.attached? %>
<% @post.images.each do |image| %>
<%= image_tag image, class:"img-fluid", size:"100x100" %>
<% end %>
<% end %>