更新:数字をプリントアウトするときJavascriptとRailsの数の検証
、彼らは実際にはまったく同じであり、両方の2つだけ小数点以下の桁を示しています。また、私のデータベースでは、これらの値は、精度8と位取り2の小数点以下の型です。
私のレールアプリにはピースモデルがあります。このモデルには、artist_cutとtotal_priceの2つのフィールドがあります。作品の編集フォームには、artist_cutに基づいて作品のtotal_priceを計算するjavascriptがいくつかあります。私は、ユーザーがそのフィールドを編集できないように、artist_cutのreadonlyフィールドを使用しました。
しかし、readonlyフィールドは簡単に壊れている可能性があります。そのため、ピースのtotal_priceが自分が望む値であることを確認する検証を追加しました。そうでない場合は、エラーをスローします。
妥当性検査は、3892と3898の間を除くすべてのartist_cutsで動作します。これらのケースでは、javascriptによって生成された値とルビによって生成された値が等しくないと考えています。これをどうすれば解決できますか?
_form.html.erb
<div class="form-group">
<%= f.label :artist_cut %><br>
<%= f.text_field :artist_cut, class: "form-control", id: "artist_cut" %>
</div>
<div class="form-group">
<%= f.label :total_price %><br>
<%= f.text_field :total_price, class: "form-control", id: "total_price", readonly: true %>
</div>
<script>
$(document).on("change", "#artist_cut", function() {
var artist_cut = $("#artist_cut").val() || 0;
$("#total_price").val(Math.ceil((((artist_cut*2.19)+0.3)/(1-0.029))*100)/100);
});
</script>
piece.rb
validates :artist_cut, presence: true, format: { with: /\A\d+(?:\.\d{0,2})?\z/ }, numericality: { greater_than: 0.5, less_than: 443378.86 }
validates :total_price, presence: true, format: { with: /\A\d+(?:\.\d{0,2})?\z/ }, numericality: true
validate :total_price_validation
def total_price_validation
return if self.total_price == ((((self.artist_cut*2.19)+0.3)/(1-0.029))*100).ceil/100.0
errors.add(:total_price, "cannot be changed")
end
おかげ
これは、浮動小数点比較を行っていることに注意してください。コンピュータは分母が2のべき乗である有理数のみを正確に表すことができるため、小さな丸め誤差が発生します。代わりに、期待値と真値の差の絶対値が正しいかどうかを確認する必要があります。 – csander
@canderこの絶対値の違いをどのように確認できますか? –
@ canderあなたが言っていることを理解しています。バリデーションでは、総価格からフォーミュラの値を差し引いた差の絶対値が0.0000000001以下であることを確認しました。これは美しく働いた。これを答えとして入力すると、正しいとマークすることができます:) –