在Ruby中带前导零的范围

5

我有一个表单,我的用户可以在我的网站上注册。

他们在表单中填写他们的出生日期:出生年份、出生月份和出生日。

因此,我使用范围来创建表单中的选择器,就像这样:

= f.select(:birthmonth, options_for_select((1..12)))

但这样无法以零开头的单个数字,像我想要的:01、02、03、04、05、06、07、08、09、10等。
我甚至尝试过以下方法,但没有成功:
= f.select(:birthmonth, options_for_select((01..12)))

有人知道如何让范围以前导零开头吗?或者有其他方法可以在验证中使用它吗?

validates_inclusion_of :birthmonth, :in => 1..12
5个回答

17
你实际上可以这样做:'01'..'12'

16

问题在于数字本身没有前导零(或者,换句话说,有无限个前导零,但从未打印出来)。要获得前导零,您需要使用字符串。幸运的是,Ruby内置了这种字符串格式化能力。

= f.select(:birthmonth, options_for_select((1..12).map {|n| "%02d" % n}))
%02d 是一种格式化说明符,意思是“如果小于两位数,则用前导零填充”。
对于验证,您需要执行相同的转换:
validates_inclusion_of :birthmonth, :in => (1..12).map {|n| "%02d" % n}

(感谢@r-dub指出这一点。)

2
为了完整起见,您应该在回答中加入正确的验证声明。validates_inclusion_of:birthmonth,:in =>(1..12).map {| n |“%02d”%n} - rwilliams
1
这个验证部分似乎是有效的。(1..12).map {|n| ("%02d" % n).to_s} - rwilliams
看起来是因为所有的月份都将被转换为字符串。而且它只验证整数。 - Lisinge
我用正确的表达式编辑了我的最后一条评论,以将它们转换为字符串。 - rwilliams
我通过Jimmy Bakers的解决方案将其更改为以下内容,成功让它工作起来了: (1..12).collect{|i| i < 10 ? 0+i : i} - Lisinge
显示剩余3条评论

2
使用rjust可能会使它更容易和美观,我猜:
(1..12).collect{ |i| i.to_s.rjust(2,'0') }

2
如果只是一个呈现问题,你可以构建 [text, value] 对,并将它们传递给 options_for_select

给定一个容器,其中元素响应于 first 和 last(例如,两个元素的数组),"lasts" 作为选项值,而 "firsts" 作为选项文本。

因此,可以这样做:
options_for_select((1..12).map {|n| ["%02d" % n, n]})

那样你应该能够保持你的验证逻辑不变。

+1 可能是最好的答案,虽然有点晚了。 - rwilliams

0

尝试给小于10的数字添加填充,就像这样:

= f.select(:birthmonth, options_for_select((1..12).collect{ |i| i < 10 ? "0#{i}" : i }))

谢谢!我可以在验证中使用吗? - Lisinge
由于这种黑客行为,你将在结果数组中得到混合类型,其中一些元素被转换为字符串,而其他元素则保留为整数。虽然在这种特定情况下可能不会造成任何问题,但这种黑客行为不应该被视为选项,至少在Ruby中不应该(这看起来像是PHP的习惯)。 - Mladen Jablanović

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接