`
peryt
  • 浏览: 55713 次
  • 来自: ...
最近访客 更多访客>>
社区版块
存档分类
最新评论
  • waiting: 既然都指定了dataType为'script'那就不必特别在b ...
    jQuery

Time in text_field

阅读更多
如果一个model中含有时间字段,那么add a new object的时候,我们可以使用datetime_select helper method to render it as a list of drop down lists, 就是,年月日小时,分都显示成一个droplist,可以选择。

当然,并不是所有人都喜欢这种输入方式。如果用户可以通过文本的方式输入时间,岂不是更好?然后由我们的程序进行解析然后存储到数据库中。

这么做意味着我们显示出来的字段跟数据库中实际存储的字段不一致。我们可以通过虚拟属性来记录这个新的string字段。

首先修改一些view中的代码
<%form_for @task do |form|%>
<%= form.text_field :due_at_string%>
<%= submit_tag "Edit task"%>
<%end%>

下面我们就要为这个虚拟属性添加getter and setter 方法了。
def due_at_string
  due_at.to_s(:db)
end
def due_at_string=(due_at_str)
  self.due_at = Time.parse(due_at_str)
end

谢天谢地,Time这个class已经给我提供了parse这个类方法,它将字符串解析成Time对象。

但是有时候,parse不能满足我们的要求,我们需要更多的时间格式,我们可以使用Chronic gem。
gem install chronic 即可。
使用时,要在你的类的开头加入 require 'chronic'
然后把Time.parse   替换成 Chronic.parse
Chronic 比 Time的一点好处是, 他可以 转换相对时间,比如tomorrow, monday, 甚至next tuesday at 8pm 之类的。
很强大把!

如果碰到不能parse的,Chronic会返回nil。
但是如果Time.parse 碰到不能parse的,它会返回一个ArgumentError Exception.
因此,如果我们使用的是Time的parse,就要添加一个rescue block,来对付这异常。
代码如下:
# def due_at_string=(due_at_str) 
#   self.due_at = Time.parse(due_at_str) 
# rescue ArgumentError 
#   @due_at_invalid = true 
# end
如果碰到这个异常,那么我们把实例变量置为true来标记。
然后在validate method中(这个方法在属性写入数据库之前会被自动执行的。)
如果这个变量为true,就往对象的errors属性中加入一个新的error(这个errors对象是一直存在着的。(从ActiveRecord继承的?也许把))

# def validate 
#   errors.add(:due_at, "is invalid") if @due_at_invalid 
# end #第一个参数是字段名称,第二个参数是要显示出来的错误信息字符串。


还有最后需要注意的一点,对于Time.parse方法,如果他的参数是一个完全不合法的参数,或者根本没有参数,那么rails不会生成一个异常,而是会使用默认的Time.now作为替代,比如我们传入一个字符串(hello world), 那么不会报错,而是会存储成current time。

但是如果传入的是32-12-2009, 那么就肯定会报错了。



分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics