Ruby
Rails
Rails6

Rails6 のちょい足しな新機能を試す16(UploadedFile#to_path編)


はじめに

Rails 6 に追加されそうな新機能を試す第16段。 今回のちょい足し機能は、 ActionDispatch::Http::UploadedFile#to_path 編です。

Rails 6.0 に ActionDispatch::Http::UploadedFile#to_path が追加されました。

これにより、

File.read uploaded_file

のように書くことができるようになりました。

今回は、アップロードファイルのフォーマットが PNG かどうかチェックするという機能を実装することにより、ちょい足し機能を試してみます。

記載時点では、Rails は 6.0.0.rc1 と 5.2.3 で確認しました。Rails 6.0.0.rc1 は gem install rails --prerelease でインストールできます。

$  rails --version

Rails 6.0.0.rc1


注意事項

今回は、あくまでも、 ActionDispatch::Http::UploadedFile#to_path の機能を試すのが目的です。

アップロードファイルのフォーマットを確認するという目的であれば、他に良い方法があるんじゃないかと思います。

また、設計の観点で見てもリファクタリングの余地のあるコードになっています。

ご了承ください。


事前準備

今回は、 Rails6 のちょい足しな新機能を試す15(Active Storage編) のコードに追加していきます。

Railsプロジェクトを作って画像ファイルをアップロードするところまでは、そちらを参照してください。


User モデルを修正する


  • User モデルに、 avatar_file 属性を追加します。

  • avatar_file のフォーマットをチェックする validation も追加します。


app/models/user.rb

class User < ApplicationRecord

# PNG フォーマットのヘッダー定数を追加
PNG_FORMAT_HEADER = ["89504E470D0A1A0A"].pack("H*")

attr_writer :avatar_file # avatar_file を追加

has_one_attached :avatar

validates :name, presence: true
validate :avatar_file_format # validation の追加

private

def avatar_file_format
if @avatar_file.present?
header = File.read @avatar_file, 8 # ちょい足し機能の確認
if header != PNG_FORMAT_HEADER
errors.add(:avatar, "is not png format file")
end
end
end
end


ここで、 @avatar_file は、 ActionDispatch::Http::UploadedFile オブジェクトです。

ActionDispatch::Http::UploadedFileto_path メソッドが追加されたことにより

header = File.read @avatar_file, 8 と書いてもエラーにならないことを確認するのが目的です。


User コントローラの修正

User コントローラで新規登録時に User モデルの avatar_fileuser_params[:avatar] を設定します。


app/controllers/users_controller.rb

  def create

@user = User.new(user_params)
@user.avatar_file = user_params[:avatar] # この行を追加

respond_to do |format|
...



User登録画面で PNG ではないファイルをアップロードする

User登録画面にアクセスして、PNGではないファイルをアップロードすると validation エラーになることが確認できます。

rails6_validation_error.png


Rails 5 では

Rails 5.2.3 で同じことを試すとエラーになります。

rails5_error.png


ソース

今回のソースは以下にあります。

https://github.com/suketa/rails6_0_0rc1/tree/try016_uploaded_file_path


参考情報