【39】【Rails】Active Storage Validations公式ドキュメントの翻訳記事
この記事はActive Storage Validations公式ドキュメントの翻訳記事です。
(注意:コード内のコメントはnoteでは非常に見にくいので意図的にコメントを直書きしています。コピペの際、不便とは思いますが、ご了承下さい。)
Active Storage Validations
If you are using active_storage gem and you want to add simple validations for it, like presence or content_type you need to write a custom validation method.
This gems doing it for you. Just use attached: true or content_type: 'image/png' validation.
アクティブ・ストレージバリデーション
active_storage gemを使用していて、presenceやcontent_typeのような単純な検証を追加したい場合は、カスタム検証メソッドを書く必要があります。
それを代行してくれるのがこのgemです。attached: trueやcontent_type: 'image/png'などのバリデーションを使うだけです。
What it can do
validates if file(s) attached
validates content type
validates size of files
validates dimension of images/videos
validates number of uploaded files (min/max required)
validates aspect ratio (if square, portrait, landscape, is_16_9, ...)
custom error messages
これでできること
ファイルが添付されているかどうかを検証する
コンテンツタイプを検証する
ファイルのサイズを検証する
画像や動画のサイズを検証します
アップロードされたファイルの数を検証する(最小/最大が必要
アスペクト比の検証(正方形、縦長、横長、is_16_9、...
カスタムエラーメッセージ
Usage
For example you have a model like this and you want to add validation.
class User < ApplicationRecord
has_one_attached :avatar
has_many_attached :photos
validates :name, presence: true
validates :avatar, attached: true, content_type: 'image/png',
dimension: { width: 200, height: 200 }
validates :photos, attached: true, content_type: ['image/png', 'image/jpg', 'image/jpeg'],
dimension: { width: { min: 800, max: 2400 },
height: { min: 600, max: 1800 }, message: 'is not given between dimension' }
validates :image, attached: true,
content_type: ['image/png', 'image/jpg'],
aspect_ratio: :landscape
end
or
class Project < ApplicationRecord
has_one_attached :preview
has_one_attached :attachment
has_many_attached :documents
validates :title, presence: true
validates :preview, attached: true, size: { less_than: 100.megabytes , message: 'is not given between size' }
validates :attachment, attached: true, content_type: { in: 'application/pdf', message: 'is not a PDF' }
validates :documents, limit: { min: 1, max: 3 }
end
More examples
Content type validation using symbols. In order to infer the correct mime type from the symbol, the types must be registered with MimeMagic::EXTENSIONS.
(シンボルを使ったコンテンツタイプの検証 シンボルから正しいMIMEタイプを推測するためには、MimeMagic::EXTENSIONSにタイプが登録されている必要があります。)
class User < ApplicationRecord
has_one_attached :avatar
has_many_attached :photos
validates :avatar, attached: true, content_type: :png
MimeMagic.by_extension(:png).to_s => 'image/png'
or
validates :photos, attached: true, content_type: [:png, :jpg, :jpeg]
or
validates :avatar, content_type: /\Aimage\/.*\z/
end
Dimension validation with width, height and in.
class User < ApplicationRecord
has_one_attached :avatar
has_many_attached :photos
validates :avatar, dimension: { width: { in: 80..100 }, message: 'is not given between dimension' }
validates :photos, dimension: { height: { in: 600..1800 } }
end
Dimension validation with min and max range for width and height:
class User < ApplicationRecord
has_one_attached :avatar
has_many_attached :photos
validates :avatar, dimension: { min: 200..100 }
Equivalent to:(下記に相当する)
validates :avatar, dimension: { width: { min: 200 }, height: { min: 100 } }
validates :photos, dimension: { min: 200..100, max: 400..200 }
Equivalent to:(下記に相当する)
validates :avatar, dimension: { width: { min: 200, max: 400 }, height: { min: 100, max: 200 } }
end
Aspect ratio validation:
class User < ApplicationRecord
has_one_attached :avatar
has_one_attached :photo
has_many_attached :photos
validates :avatar, aspect_ratio: :square
validates :photo, aspect_ratio: :landscape
you can also pass dynamic aspect ratio, like :is_4_3, :is_16_9, etc
:is_4_3, :is_16_9 のように、動的なアスペクト比を渡すこともできます。
validates :photos, aspect_ratio: :is_4_3
end
Internationalization (I18n)
Active Storage Validations uses I18n for error messages. For this, add these keys in your translation file:
en:
errors:
messages:
content_type_invalid: "has an invalid content type"
file_size_out_of_range: "size %{file_size} is not between required range"
limit_out_of_range: "total number is out of range"
image_metadata_missing: "is not a valid image"
dimension_min_inclusion: "must be greater than or equal to %{width} x %{height} pixel."
dimension_max_inclusion: "must be less than or equal to %{width} x %{height} pixel."
dimension_width_inclusion: "width is not included between %{min} and %{max} pixel."
dimension_height_inclusion: "height is not included between %{min} and %{max} pixel."
dimension_width_greater_than_or_equal_to: "width must be greater than or equal to %{length} pixel."
dimension_height_greater_than_or_equal_to: "height must be greater than or equal to %{length} pixel."
dimension_width_less_than_or_equal_to: "width must be less than or equal to %{length} pixel."
dimension_height_less_than_or_equal_to: "height must be less than or equal to %{length} pixel."
dimension_width_equal_to: "width must be equal to %{length} pixel."
dimension_height_equal_to: "height must be equal to %{length} pixel."
aspect_ratio_not_square: "must be a square image"
aspect_ratio_not_portrait: "must be a portrait image"
aspect_ratio_not_landscape: "must be a landscape image"
aspect_ratio_is_not: "must have an aspect ratio of %{aspect_ratio}"
aspect_ratio_unknown: "has an unknown aspect ratio"
"無効なコンテンツタイプを持つ"
"サイズ %{file_size} が必要な範囲にない"
"合計数が範囲外です"
"有効な画像ではありません"
"サイズは %{width} x %{height} pixel 以上でなければなりません。"
"幅が%{width}×%{height}ピクセル以下でなければなりません"
"width は %{min} と %{max} pixel の間に含まれない"
"高さは %{min} と %{max} ピクセルの間に含まれません。"
"width は %{length} pixel 以上でなければなりません。"
"高さは%{length} pixel以上でなければならない"
"width は %{length} pixel 以下でなければならない"
"高さは%{length} pixel以下でなければならない"
「幅は %{length} pixel と同じでなければならない。
"高さは%{length} pixelに等しくなければならない"
"正方形の画像であること"
"縦長の画像であること"
"横長の画像でなければならない"
"アスペクト比が%{aspect_ratio}の割合でなければならない"
"アスペクト比が認識しません"
In some cases, Active Storage Validations provides variables to help you customize messages:
The "content_type_invalid" key has two variables that you can use, a variable named "content_type" containing the content type of the send file and a variable named "authorized_types" containing the list of authorized content types.
The variables are not used by default to leave the choice to the user.
Active Storage Validationsでは、メッセージをカスタマイズするための変数を用意している場合があります。
content_type_invalid "キーには、送信ファイルのコンテンツタイプを含む "content_type "という変数と、許可されたコンテンツタイプのリストを含む "authorized_types "という変数の2つの変数があります。
これらの変数はデフォルトでは使用されず、ユーザーが選択できるようになっています。
For example :
content_type_invalid: "has an invalid content type : %{content_type}"
Also the "limit_out_of_range" key supports two variables the "min" and "max".
(また、"limit_out_of_range "キーは、"min "と "max "の2つの変数をサポートしています。)
For example :
limit_out_of_range: "total number is out of range. range: [%{min}, %{max}]"
Installation
Add this line to your application's Gemfile:
# Rails 5.2 and Rails 6
gem 'active_storage_validations'
# Optional, to use :dimension validator or :aspect_ratio validator
And then execute:
(# オプションとして、:dimension validator または :aspect_ratio validator を使用します。
gem 'mini_magick', '≧ 4.9.5'
RSpec
In spec_helper.rb, you'll need to require the matchers:
require 'active_storage_validations/matchers'
And include the module:
RSpec.configure do |config|
config.include ActiveStorageValidations::Matchers
end
Example (Note that the options are chainable):
describe User do
it { is_expected.to validate_attached_of(:avatar) }
it { is_expected.to validate_content_type_of(:avatar).allowing('image/png', 'image/gif') }
it { is_expected.to validate_content_type_of(:avatar).rejecting('text/plain', 'text/xml') }
it { is_expected.to validate_dimensions_of(:avatar).width(250) }
it { is_expected.to validate_dimensions_of(:avatar).height(200) }
it { is_expected.to validate_dimensions_of(:avatar).width(250).height(200).with_message('Invalid dimensions.') }
it { is_expected.to validate_dimensions_of(:avatar).width_min(200) }
it { is_expected.to validate_dimensions_of(:avatar).width_max(500) }
it { is_expected.to validate_dimensions_of(:avatar).height_min(100) }
it { is_expected.to validate_dimensions_of(:avatar).height_max(300) }
it { is_expected.to validate_dimensions_of(:avatar).width_between(200..500) }
it { is_expected.to validate_dimensions_of(:avatar).height_between(100..300) }
it { is_expected.to validate_size_of(:avatar).less_than(50.kilobytes) }
it { is_expected.to validate_size_of(:avatar).less_than_or_equal_to(50.kilobytes) }
it { is_expected.to validate_size_of(:avatar).greater_than(1.kilobyte) }
it { is_expected.to validate_size_of(:avatar).greater_than_or_equal_to(1.kilobyte) }
it { is_expected.to validate_size_of(:avatar).between(100..500.kilobytes) }
end
Minitest
(割愛します)
Todo
verify with remote storages (s3, etc)
verify how it works with direct upload
better error message when content_size is invalid
add more translations
リモートストレージ(s3など)での検証
ダイレクトアップロードでの動作確認
content_sizeが無効な場合のエラーメッセージの改善
翻訳の追加
Known issues
There is an issue in Rails which it possible to get if you have added a validation and generating for example an image preview of attachments. It can be fixed with this:
(既知の問題
Railsでは、バリデーションを追加して添付ファイルの画像プレビューなどを生成した場合に発生する可能性がある問題があります。この問題は修正されました。)
<% if @user.avatar.attached? && @user.avatar.attachment.blob.present? && @user.avatar.attachment.blob.persisted? %>
<%= image_tag @user.avatar %>
<% end %>
公式ドキュメントのリンク
使用したツール
最後に
私がブログを書く目的は、素晴らしい本や、素晴らしい方々の技術記事を知って頂きたいからです。ぜひ、上記の参考文献を見て下さい。(noteなので広告とかは一切ありません。)
現在、株式会社grabssに行くために最後の悪あがきをしています!!
現在の進行状況
この記事は39件目の投稿。目標まで後11件。
よろしければ、スキボタン及びサポートお願いします。勉強の励みになります。