Ajaxで手数料と利益の計算をするの巻② モデル単体テスト
JavaScript 実装が完了し、最後の詰めでモデルのバリデーションをかけ直しました。
販売価格は、
- ¥300~¥9,999,999の間のみ保存可能であること。
- 価格は半角数値のみ保存可能であること。
こちらは numericality
でいけそう。
さっそく実装します。
こんな感じ。
値として数値のみを許す
only_integer: true
¥300~¥9,999,999の間のみ許可
greater_than_or_equal_to: 300,less_than_or_equal_to: 9_999_999
これで販売価格のバリデーション設定は完了! ちなみに、数字の間にあるアンダーバーは表示上数字を見やすくするためのもので、 データを取得しても『1_000』であれば『1000』となります。 Web上でカンマ区切りで表示させることもできます。
そして、画像で示してある通り、わたしはmessageオプションを使いました。 それが沼の始まりでした。 というか、バリデーションの仕組みを理解していなかったのがいけなかったんです。
たとえば、
only_integer: true
でバリデーションをかけると、
デフォルトのエラーメッセージは「must be an integer」なんです。
同様に、
greater_than
の場合は「must be greater than %{count}」、
less_than
の場合は「must be less than %{count}」なんです。
Active Record バリデーション - Railsガイド
そこをもうみんな一緒でいいよねー、ってことで「is invalid」 無効です、にしてたのにテストファイルとモデルファイルのエラーメッセージの統合性が取れていなかったものだから エラー、エラーのオンパレードで、エラーメッセージの始まりは大文字でなければいけない、とか 「can't be blank」なのに「is valid」になっているとかでひとつずつエラーを解消していったのですが、 最後に残ったのが販売価格のところ。
販売価格は値が空ではいけない、半角数字でなければいけない、指定の範囲でなければいけない、と複数のバリデーションがかかっており ChatGPTに聞いてみたり検索したりする中でいろいろな意見があるわけです。 それらすべてを試してみて、最終的にこちら。
require 'rails_helper' RSpec.describe Item, type: :model do before do @item = FactoryBot.build(:item) end describe '商品情報登録' do context '商品情報が登録できるとき' do it '正常に登録できるとき' do expect(@item).to be_valid end end context '商品情報が登録できないとき' do it 'itemが空では登録できない' do @item.name = '' @item.valid? expect(@item.errors.full_messages).to include "Name can't be blank" end it '商品画像が空では登録できない' do @item.image = nil @item.valid? expect(@item.errors.full_messages).to include "Image can't be blank" end it 'カテゴリーが空では登録できない' do @item.category_id = '' @item.valid? expect(@item.errors.full_messages).to include "Category can't be blank" end it '商品の状態が空では登録できない' do @item.condition_id = '' @item.valid? expect(@item.errors.full_messages).to include "Condition can't be blank" end it '配送料の負担情報が空では登録できない' do @item.postage_type_id = '' @item.valid? expect(@item.errors.full_messages).to include "Postage type can't be blank" end it '発送元の地域情報が空では登録できない' do @item.prefecture_id = '' @item.valid? expect(@item.errors.full_messages).to include "Prefecture can't be blank" end it '発送までの日数情報が空では登録できない' do @item.shipping_time_id = '' @item.valid? expect(@item.errors.full_messages).to include "Shipping time can't be blank" end it '価格情報が空では登録できない' do @item.price = nil @item.valid? expect(@item.errors.full_messages).to include "Price can't be blank" end it '価格は¥299以下の場合は登録できない' do @item.price = '299' @item.valid? expect(@item.errors.full_messages).to include "Price is invalid" end it '価格は¥1,000,000以上の場合は登録できない' do @item.price = '10000000' @item.valid? expect(@item.errors.full_messages).to include "Price is invalid" end it '価格は半角数値でなければ登録できない' do @item.price = 'ああああ' @item.valid? expect(@item.errors.full_messages).to include "Price is invalid" end end end end
やっと通りましたー!
エラーメッセージも適当に入れたらだめなのね、とかデフォルト値があるのね、とか めっちゃ勉強になりました。 さらに続く。