質問: Railsで画像をS3にアップロードする機能を作成したいと考えています。 しかしここでValidation周りの設計に悩んでおります。 まずサイトの機能としては、入力フォーム画像のURLを指定しSubmitすると、それがS3にアップロードされます またアップロードした写真を管理できるよう、データベースに画像に紐付いたレコードであるPicutreレコードを保存したいです。 またPictureテーブルは将来的にはタグなどを管理させたいですが、現状はカラムはありません。 プログラムの流れを説明させていただくと、 ・入力フォームに写真のURLを指定し、Submitします。 ・サーバ側で、まずその入力がURLの表記として正しいかチェックします。 ・そのURLからファイルをTmpFileにダウンロードします。 ・Pictureレコードを作成し、保存します。 ・画像をS3にアップロードします。この時のファイル名はPictureのカラムのIDにしたいと考えています。 ・最後にResponseを返します。 ここでValidation周りをどのように設計すれば良いのかわからず困っています。 まず入力された画像URLのチェックです。 このURLは、Pictureテーブルには存在しないカラムです。なので、モデルにvalidatesをかけないように思えます。 私としては調べたところ、FormObjectというのがあり、これを使うことで仮想的にmodelを作れ、Validationをかけるようでした。なので、ImageUploadFormのようなクラスをコントローラ内に作り、ここで入力されたURLがURLとして正しい形式かチェックするのが良いように思えました。 この設計は正しいでしょうか? 次にURL先からデータをダウンロードする部分です。 ここもユーザが入力するものなので、架空のアドレスなどが指定される場合もあると思います。 ではこれも先ほどのImageUploadFormのValidationの処理の一環なのでしょうか? ただ、実際にファイルをダウンロードするので、戻り値はTmpFileのように思えます。これはvalidatesでどのようにかけば良いでしょうか? 最後にValidationとは関係ないですが、 S3にアップロードするための画像のファイル名を、レコードのIDにしたいため、先にレコードの保存処理していることです。 これだともしS3へのアップロードがなんらかの理由で失敗した場合、レコードを明示的に削除する必要性があります。 もし何か他に良い方法があれば、知りたいです。 抽象的な質問で申し訳ないです。何かお気付きの点などありましたら、ご回答いただけると助かります。
回答: > > このURLは、Pictureテーブルには存在しないカラムです。なので、モデルにvalidatesをかけないように思えます。 > > > いえ。書けます。 ``` class Picture < ApplicationRecord attr :url validates_presence_of :url end ``` こんな感じで、DBのカラムに対応しない属性をモデルに持たせ、バリデーションを定義することもできます。 素直に実装するのであれば、上記のようにPictureにurl属性を定義し、適当なコールバックで画像のダウンロードやアップロードを実装する形になります。 ところで、CarrierWaveという定番のアップローダのライブラリがありますので、それを使う方が簡単で確実かと思います。