Ruby on Rails
基礎5

  • さて、次は画像のバリデーションの実装です。まずは「ファイルの種類」のバリデーションから行いましょう。
    • 「 app/models/user.py 」ファイルを開いて、以下のようにしてください。

画像のバリデーション

  • このコードでは「 validate :img_path_check? 」の部分で、img_path_check? というカスタムバリデーション(自分で作ったバリデーション)を実行しています。
    • 今までは「 validates 」でしたが、カスタムバリデーションの場合は「 validate 」になります。(sがない)
  • img_path_check? は下の赤枠部分で追加したメソッドで、「if !img_path.file.extension.in?(%w[jpg jpeg gif png]) 」の部分で、「アップロードされた画像の拡張子( . の後の部分)の名前が、[jpg jpeg gif png]に含まれていないか?」を判定しています。
    • ※「img_path.file.extension.in?(%w[jpg jpeg gif png])」だと、「含まれているか?」の判定ですが、最初に ! が付いているので、反対の意味になります。
    • つまり「!img_path.file.extension.in?(%w[jpg jpeg gif png])」なので、「含まれていないか?」の判定になります。
  • 含まれていなかった場合、つまり一般的な画像ファイルの jpg、jpeg、gif、png じゃない場合は、「errors.add(:img_path, "アップロードできるファイルは (jpg, jpeg, gif, png)だけです")」の部分で、エラーメッセージを追加しています。
    • また、「 errors.add 」が実行されると、登録処理も失敗になりますので、これで「画像の種類のバリデーション」はOKです。

画像のバリデーション

  • 「 jpg、jpeg、gif、png」は、一般的な画像の拡張子(ファイル形式)です。
  • 画像のファイルといえど、色々が種類があり、それぞれ「圧縮方式」「色深度(色の数)」などが違います。
    • 圧縮とは「なるべく見た目はそのままに、サイズを小さくする」ことを言います。次へ。

データ容量の単位

  • 代表的な画像のファイル形式と、それぞれの違いをまとめるとこんな感じです。※別に覚える必要はありません。
ファイル形式 特徴 圧縮方式 色深度 透明度サポート メタデータ
JPEG(JPG) 高圧縮率で写真向け 非可逆圧縮 24ビット なし あり
PNG 透明度を含む高品質 非可逆圧縮 8, 24, 32ビット あり あり
GIF アニメーション対応 可逆圧縮 8ビット あり なし
BMP 非圧縮の高品質 非圧縮 1, 4, 8, 24ビット あり あり
TIFF 高品質で多様なデータ 可逆圧縮、非可逆圧縮 1, 8, 16, 24, 32ビット あり あり
WEBP 高圧縮率で高品質 非可逆圧縮、可逆圧縮 24ビット あり あり

非可逆とは、元に戻せないこと、

可逆とは、元に戻せることです。

色深度とは「どれくらいの色の種類が使えるか?」です

数字が大きいほど、多くの色が使えます。

透明度とは「画像の背景部分を透明に出来るか?」です。

透明度に対応していない場合は、白色になります。

メタデータとは「ファイルの作成日」や「GPS情報」のようなデータです。

  • ちなみに jpg と jpeg はまったく同じファイル形式です。
  • 歴史的な経緯で「jpg でも良いよ!」となりましたが、ファイルの形式としてはどちらも「 jpeg 」のことになります。
  • 次に「画像サイズのバリデーション」を考えてみましょう。
  • 巨大なサイズをアップロードされてしまうと、サーバの容量が圧迫されてしまうので、ある程度の大きさに制限しないといけませんよね。
  • でも「巨大なサイズ」って言われても「逆に一般的な画像のサイズってどんくらいやねん?」と、なりますよね。
  • そもそも「パソコンの容量」ってのがどれくらいなのか?や、どんな単位なのか?も、知っていないといけませんので、まずはそこらへんの話をしておきたいと思います。次へ。

画像のバリデーション

データ容量の単位

  • コンピュータの世界で使われる基本的なデータ単位を知っておきましょう。
  • まず、前提としてコンピュータや、通信の世界での最小の単位は「ビット(bit)」という単位です。
  • このビットは「0か1か」という2通りのデータだけを扱える大きさです。
  • これだと流石に小さすぎるので、現在のパソコンでは「8bit を1つにまとめて」使います。
  • この「8bit を1つにまとめた単位を 1バイト(byte)」と言います。
  • そのため、パソコンでの最小単位は、この「1バイト」だと思って問題ありません。
  • この1バイトは、256通りのデータを保存できる大きさになります。
    • 簡単に言うと0~255(256通り)までの数字を扱えるサイズです。
  • このバイトを基準にして、右の表の単位が使われます。
呼び方 サイズ 省略文字
バイト(byte) 8bit B
キロバイト(kilobyte) 1000B KB
メガバイト(megabyte) 1000KB MB
ギガバイト(gigabyte) 1000MB GB
テラバイト(terabyte) 1000GB TB
ペタバイト(petabyte) 1000TB PB

30年以上前の古いパソコンや、特殊なコンピュータでは【8bit = 1B】ではないですが、現在はほぼ存在しないので、気にする必要はありません。

データ容量の単位

  • 一般的に売られているパソコンの容量として、ピンキリではありますが、最近では「500GBから1TB」ぐらいが多いかと思います。
  • 次に画像のサイズですが、これも色々ですが、最新のスマホで写真を撮ると「1M~10M」ぐらいになると思います。
  • では、ちょっと問題です。
    • 「1枚5Mの画像を、1TBの保存領域(ストレージ)に、最大何枚保存できるか?」を考えてみましょう。
  • 1TBは1MBの1,000,000倍、つまり 1,000,000MB なので、1000000 ÷ 5 で 200,000枚になります。このように考えてください。
  • では、今のサイトのストレージは?というと、replit では左下らへんに表示されています。
  • replitでは、1アカウントごとにストレージが割り当てられていますので、青色の部分が今開いているサイトで使用している容量です。
  • 全体で 10GiB というストレージ容量になっています。
  • 「GiB」というのは「GB」とほぼ同じと考えてください。

データ容量の単位

  • 先ほど出てきた「GiB」(キビバイト)は「正確な表示の単位」です。
  • 実は、先ほどの表では「1GBは、1000MB」と書いていましたが、コンピュータの世界では「正確には1024MB」です。(つまり1024倍)
    • 同じように、「1MBは、1024B」です。なんだか中途半端な数ですよね?
  • コンピュータは、0か1だけで数を表す「2進数」というものを使っていますので、2 の 10乗である 1024 の方が実はキリの良い数字なのです。
  • ただし一般的にコンピュータの外の世界では「1MBは、1000B」なので、例えば「1TBのHDD」を買ってきて、パソコンにつなぐと、最初っから931GBしかありません。
    • 個人的には「詐欺じゃねーか!」と思いますが「1MBを、1000Bとする」というのは国際的にも認められているので、仕方ありません。
  • これじゃイカン!と新たな規格として【キビバイト(KiB)→メビバイト(MiB)→ギビバイト(GiB)、テビバイト(TiB)】という規格が考え出されました。
  • このB→KiB→MiB→GiB→TiB】は、必ず1024倍であることを意味します。つまり1TiB(テビバイト)は、コンピュータ上でも1024GiB(ギビバイト)であるということです。
    • ​ただ、これはあまり知られていないので、日本ではほとんど使われませんがReplitでは、ちゃんとGiBが使われていますね。
呼び方 サイズ 省略文字
バイト 8bit B
キビバイト 1024B KiB
メビバイト 1024KiB MiB
ギビバイト 1024MiB GiB
テビバイト 1024GiB TiB
ペビバイト 1024TiB PiB

画像のバリデーション

  • さて、とりあえず replit のストレージのサイズはわかりましたが、かなり小さいサイズです。
  • すべて画像用に使えたとしても、5Mの画像だと2,000枚程度です。
    • 当然画像以外にも必要なファイルやデータがありますので、実質1,000枚ぐらいでしょうか。
  • さらに「画像は保存出来れば良い」というわけでもなく「画像を読み込む(表示させる)時間」も考慮する必要があります。
  • 見ている人の画面に画像を表示させるには、サーバからHTMLと一緒に画像のデータも送って、それを見ている人のパソコンやスマホが受け取ってから画面に表示されます。
    • つまり大きいサイズの画像は通信する容量も大きくなり、その分時間もかかることになります。
    • 画像はなるべく小さいほうが良いです。(もちろん小さくなると、ぼやけたような画像になります)
  • 以上のことから、ココでは「アップロードできる画像は最大1Mまで」というバリデーションにしたいと思います。

画像のバリデーション

  • 「 app/models/user.py 」の「 img_path_check 」メソッドに以下のように追加してください。
  • これで1M以上のファイルの場合は、登録されないようになりました。
  • 同じことを「 app/models/book.py 」の方にもしておきましょう。

画像のバリデーション

  • これでとりあえず画像のバリデーションもOKとします。
  • もう一つのサイトにも同じようにして、画像のバリデーションを行いましょう。
  • さて、以上で「Ruby on Reils基礎コース」も終了です。
  • 本当はもっと色々やることは考えられるのですが、キリがないので、これでひとまずの完成としたいと思います。
  • 基礎的なことは結構やりましたが、まだまだ奥の深いのWEBの世界です。
  • 思いつく限り、色々なサイトを作ってみて知識を深めていってください。
    • お疲れ様でした。

お疲れ様でした

  • Railsに関してはひとまず終わりです。
  • 次のステップは相談してください。

お疲れ様です。