###画像の検証
アップロードされた画像に対する制限がないため、もしユーザーが巨大なファイルを上げたり、無効なファイルを上げると問題が発生してしまいます。この欠点を直すために、画像サイズやフォーマットに対するバリデーションを実装しましょう。
####Active Storageバリデーション用のgemを追加する
Gemfile
source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
gem 'rails', '6.0.3'
gem 'active_storage_validations', '0.8.2'
gem 'bcrypt', '3.1.13'
.
.
.
bundle install
####画像バリデーションを追加
app/models/micropost.rb
class Micropost < ApplicationRecord
# ApplicationRecordを継承したモデルが作られます
belongs_to :user
# userモデルとの間に「1対1」のつながりが設定
# 割り当てる
has_one_attached :image
# 指定のモデルと、アップロードされたファイルを関連付ける
# この場合はimageを指定してMicropostモデルと関連付けます
default_scope -> { order(created_at: :desc) }
# データベースから要素を取得したときの、
# デフォルトの順序を指定するメソッドです。
# order(created_at:desc) でこのカラムの順序に指定する
# デフォルトで最も古い投稿が最初に投稿が表示されている。
# :desc 新しい投稿から古い投稿の順になります
# -> ラムダ式という。
validates :user_id, presence: true
# presence これは存在するか
# presenceメソッドはオブジェクトが存在すればそのオブジェクトを返し、
# オブジェクトが存在しなければnilを返すメソッドとなります
validates :content, presence: true, length: { maximum: 140 }
# 最大140文字まで
validates :image, content_type: { in: %w[image/jpeg image/gif image/png],
# content_typeを検査することで画像をバリデーション
# %w 配列を作る
message: "must be a valid image format" },
size: { less_than: 5.megabytes,
# 画像の最大サイズを5 MBに制限
message: "should be less than 5MB" }
end
###jQueryでファイルサイズをチェックする
app/views/shared/_micropost_form.html.erb
.
.
.
</span>
<% end %>
<script type="text/javascript">
// micropost_imageを含んだ要素を見つけ出し、この要素を監視しています。
$("#micropost_image").bind("change", function() {
var size_in_megabytes = this.files[0].size/1024/1024;
if (size_in_megabytes > 5) {
// // サイズが大きすぎたら
alert("Maximum file size is 5MB. Please choose a smaller file.");
// メッセージを表示する
$("#micropost_image").val("");
}
});
</script>
####有効な画像フォーマットだけを許可する
app/views/shared/_micropost_form.html.erb
</div>
<%= f.submit "Post", class: "btn btn-primary" %>
<span class="image">
<%= f.file_field :image, accept: "image/jpeg,image/gif,image/png" %>
<!--app/models/micropost.rbのhas_one_attached :imageに対応する-->
<!--"image/jpeg,image/gif,image/png ファイルの種類-->
<!--複数の種類と思われる-->
</span>
<% end %>
<script type="text/javascript">
.
.
.
###演習
1.
5MB以上の画像ファイルを送信しようとした場合、どうなりますか?
選択できない。
2.
無効な拡張子のファイルを送信しようとした場合、どうなりますか?
選択できない。