Ren*_*ndy 12 ruby validation datetime ruby-on-rails ruby-on-rails-4
我在客户端使用tsjzt:http://pellepim.bitbucket.org/jstz/ 来获取我存储在用户对象中的当前用户时区.
这很好用,给了我像"欧洲/伦敦"这样的时区.我想验证何时将其传递给模型,它是一个有效的时区,因为发生了一些不好的事情.
所以我发现了这个问题:在Heroku上验证Rails应用程序的用户时区问题,并尝试了这个验证:
validates_inclusion_of :timezone, :in => { in: ActiveSupport::TimeZone.zones_map(&:name) }
Run Code Online (Sandbox Code Playgroud)
但是名称与tzinfo不同.我认为我的客户端检测到时区字符串"Europe/London"本质上是TimeZone类中TimeZone映射的值组件而不是名称 - 在本例中将设置为"London".
所以我尝试了这个:
validates_inclusion_of :timezone, :in => { in: ActiveSupport::TimeZone.zones_map(&:tzinfo) }
Run Code Online (Sandbox Code Playgroud)
对于另一个SO问题或我改变的问题的原始答案:tzinfo都没有工作,因为他们都失败验证时:时区是"欧洲/伦敦",显然这是一个有效的时区!
我对这个时区验证做错了什么,我该如何解决?
Mat*_*son 18
看起来你想要这个:
validates_inclusion_of :timezone,
:in => ActiveSupport::TimeZone.all.map { |tz| tz.tzinfo.name }
Run Code Online (Sandbox Code Playgroud)
在我的机器上,该列表包含以下名称:
...
"Europe/Istanbul",
"Europe/Kaliningrad",
"Europe/Kiev",
"Europe/Lisbon",
"Europe/Ljubljana",
"Europe/London",
...
Run Code Online (Sandbox Code Playgroud)
但是,更清洁的解决方案是自定义验证方法,如下所示:
validates_presence_of :timezone
validate :timezone_exists
private
def timezone_exists
return if timezone? && ActiveSupport::TimeZone[timezone].present?
errors.add(:timezone, "does not exist")
end
Run Code Online (Sandbox Code Playgroud)
这在它接受的值中更灵活:
ActiveSupport::TimeZone["London"].present? # => true
ActiveSupport::TimeZone["Europe/London"].present? # => true
ActiveSupport::TimeZone["Pluto"].present? # => false
Run Code Online (Sandbox Code Playgroud)
一个更轻量级和高性能的解决方案是使用TZInfo::Timezone.all_identifiers而不是从ActiveSupport::TimeZone.all.
validates :timezone, presence: true, inclusion: { in: TZInfo::Timezone.all_identifiers }
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2903 次 |
| 最近记录: |