見出し画像

【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 %>

公式ドキュメントのリンク

使用したツール

DeepL翻訳

 最後に
私がブログを書く目的は、素晴らしい本や、素晴らしい方々の技術記事を知って頂きたいからです。ぜひ、上記の参考文献を見て下さい。(noteなので広告とかは一切ありません。)

現在、株式会社grabssに行くために最後の悪あがきをしています!!
現在の進行状況
この記事は39件目の投稿。目標まで後11件。

よろしければ、スキボタン及びサポートお願いします。勉強の励みになります。

この記事が気に入ったらサポートをしてみませんか?