Rails5.2でActiveStrageというファイルアップロード系の機能が新しく追加されましたね(・∀・)
ちょっと自分が作っているアプリで使ってみたので使い方をφ(..)メモメモ
ActiveStrageとは?
ActiveStrageとは、Rails5.2から実装されたファイルアップロード機能です。
今までは画像等をアップロードするときにはCarrierWave
やShrine
といったGemを使うことが多かったと思いますが、それがRailsだけで簡単に出来るようになりました🙌
ActiveStrageを使ってみた
ソースだけ見たい方はこちら👀
準備
まずはActiveStrageを使うために下記コマンドを実行します。
$ rails active_storage:install $ rails db:migrate
そして、ファイルのアップロード先を設定します。アップロード先はconfig.active_storage.service
に設定されたkeyでstarage.yaml
を参照します。
strage.yml
local: service: Disk root: <%= Rails.root.join("storage") %>
development.rb
# Store uploaded files on the local file system (see config/storage.yml for options) config.active_storage.service = :local
ファイルをアップロードしてみる
まずはModelにファイルのプロパティを定義します。1つのファイルをアップロードする場合はhas_one_attached
、複数のファイルをアップロードする場合はhas_many_attached
を使用します。
class User has_one_attached :avatar end
次にcontrollerとviewを次のように実装します。
新規登録の場合は、パラメーターにavator
を追加してnewの引数に渡してあげるだけでいいのですが、既存レコードにファイルを設定する場合は.avatar.attach
を使用する必要があります。
controller
def create @user = User.new(user_params) if @user.save redirect_to @user, notice: message('user', 'create') else render :new end end def update @user = User.find(current_user.id) @user.avatar.attach(params[:user][:avatar]) if @user.update(user_params) redirect_to @user, notice: message('user', 'update') else render :edit end end private def user_params params.require(:user).permit(:email, :name, :password, :password_confirmation, :avatar) end
view
= form_for @user do |f| %div.form-group = f.label :avatar = f.file_field :avatar, class: 'file-inputs' .actions = f.submit t('common.save'), class: 'btn btn-primary'
これで、画面からアップロードが出来るようになりました!!(・∀・)
バリデーションを実装してみる
しかし、このままでは画像以外がアップロードされてしまったり、大きなファイルがアップロードされてしまうといったことが防げません。。。
ActiveStrageは、まだvalidationの機能が無いので、自分で実装する必要があります😥
今回は、サイズのチェックと画像のみをアップロード可能とするようなバリデーションをサンプルとして載せましたので、参考までに。
class User < ApplicationRecord validate :file_validation, if: -> { avatar.attached? } private def file_validation if avatar.blob.byte_size > 1_000_000 file_raise_error('のファイル容量が大きすぎます') elsif !avatar.blob.content_type.starts_with?('image/') file_raise_error('は、画像以外はアップロード出来ません') end end def file_raise_error(message) avatar.purge errors.add(:avatar, message) end end
おわりに
ActiveStrageはシンプルなファイルアップロード機能を実装するのであれば、お手軽に実装出来てよさそうに感じました(・∀・)
しかし、バリデーションを独自で実装する必要があるため、あまり複雑なアップロード処理にはまだ向かなそうですね😥