2017-08-22 2 views
0

小数点以下の桁のビジネスモデルがあります。その値は0.00と999.99の間でなければなりません。だから私は小数点フィールドを作成し、モデルにバリデーションを追加しました。私が1000より大きいか0未満の小数値でOrderオブジェクトを作成するとRuby on Rails Decimalプロパティの検証

class Order < ApplicationRecord 

    validates :price, format: { with: /\A\d+(?:\.\d{0,2})?\z/ }, numericality: { greater_than: 0, less_than: 1000 } 

end 

、私は私が期待されるエラーを取得し、それは大丈夫です。 「数値:{greater_than:0、less_than:1000}」の検証が期待通りに機能することがわかります。

小数点以下の桁数が45.45554または45.45666のOrderオブジェクトを作成しようとすると、railsはそのオブジェクトを価格値45.45で保持します。フォーマットエラーが発生すると予想していますが、 フォーマットの検証は機能しません。

私は間違っていますか?

提案、

ありがとう。

答えて

1

価格フィールドの精度はどのくらいですか? docs

precision数値の桁数の合計を表す小数フィールドの精度を定義します。

価格は2の精度しかないと仮定しています。そのため、丸められています。

+0

Yeap、priceの精度は2です。私には精度がないと仮定すると、フォーマットの検証が必要です。しかし、いずれにせよ、それは動作しません。 –

+0

私はあなたの精度を向上させるでしょう、もしあなたが小数点以下を一定量必要としたいと思ったら、それは別の話ですが、私はあなたのユースケースを理解していません。 – at0misk

0

値はセッターによって小数に変換されます。つまり、フォーマットの検証は常に成功するということです。

妥当性検査が必要な場合は、カスタム検証でread_attribute_before_type_castを使用してください。

class Order < ApplicationRecord 

    validates :price, numericality: { greater_than: 0, less_than: 1000 } 
    validates :price_format 
    PRICE_REGEXP = /\A\d+(?:\.\d{0,2})?\z/.freeze 

    private 
    def price_format 
    unless read_attribute_before_type_cast('price') =~ PRICE_REGEXP 
     errors.add('price', 'must match the correct format') 
    end 
    end 
end 
関連する問題