[英]Validating decimal scale in Ruby on Rails
I'm new to Ruby on Rails.我是 Ruby on Rails 的新手。 I have the following model:我有以下 model:
class Logo < ApplicationRecord
validates :name, presence: true, length: { maximum: 255 }
validates :price, presence: true,
numericality: { greater_than_or_equal_to: 0 }
validates :stitch_count, presence: true,
numericality: { greater_than: 0, only_integer: true }
end
Every logo has a price.每个标志都有一个价格。 I want to validate the scale of the price.我想验证价格的规模。 It must accept the following: [10.44, 12.1, 16] and reject the following: [10.123, 13.11111, 16.123], as these are obviously not valid prices.它必须接受以下内容:[10.44, 12.1, 16] 并拒绝以下内容:[10.123, 13.11111, 16.123],因为这些显然不是有效价格。 I've tried validating by format using the following regex: /\A\d+(?:\.\d{0,2})?\z/
, which, according to another poster on Stack Overflow , validates for at most 2 decimal places.我尝试使用以下正则表达式按格式验证: /\A\d+(?:\.\d{0,2})?\z/
,根据Stack Overflow上的另一张海报,最多验证 2小数位。 It doesn't work.它不起作用。 Another poster on Stack Overflow pointed out that the number of decimal places only matters when the value is a string, and that by the time the validator runs, it's no longer a string. Stack Overflow上的另一位发帖人指出,小数位数仅在值是字符串时才重要,并且当验证器运行时,它不再是字符串。 His suggestions, as well as a few more, don't work.他的建议以及其他一些建议都不起作用。 So how would I run a regex on a decimal?那么我将如何在小数上运行正则表达式? You would think Rails would have something to validate if a number is a valid price or not.你会认为 Rails 有一些东西可以验证一个数字是否是一个有效的价格。
I run the following test:我运行以下测试:
def setup
@logo = Logo.new(name: "ASG Security", price: 12, stitch_count: 15000, note: "Ali")
end
test "price scale must be less than 2" do
@logo.price = 14.995
assert_not @logo.valid?
end
You could use the money gem , which I've used, or maybe try this rails wrapper for it which provides premade money validations.您可以使用我使用过的money gem ,或者尝试这个提供预制货币验证的 rails wrapper 。
Generally it's not a good idea to use decimals for currencies.一般来说,对货币使用小数并不是一个好主意。
If you're using USD, you can make the attribute price_cents
instead of price
.如果您使用美元,您可以使用属性price_cents
而不是price
。
For example:例如:
Rather than passing 1.23
as price, you would pass 123
as price_cents.与其将1.23
作为价格传递,不如将123
作为 price_cents 传递。
And echoing what @chad_ mentioned, it's a good idea to use the Money gem.并呼应@chad_ 提到的内容,使用Money gem 是个好主意。 (Additionally the Money gem will expect currencies as "cents") (此外,Money gem 将期望货币为“美分”)
By the time the validation runs, the price is no longer a String
.到验证运行时,价格不再是String
。 You can verify that a number has at most two decimals by comparing price
with price.round(2)
:您可以通过将price
与price.round(2)
进行比较来验证一个数字最多有两位小数:
10.44 == 10.44.round(2) # true
10.123 == 10.123.round(2) # false
You can write a custom validator that makes this comparison and adds an error to the attribute in case it is not equal.您可以编写一个自定义验证器来进行此比较并向属性添加错误以防它不相等。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.