我读过很多文章,完成了我的作业。我有时间存储为UTC,每个用户都设置自己的时区等。这是我遇到的问题:
Time.zone
=> GMT-05:00 Eastern Time US Canada
t = Ticket.first
t.hold_until = "Jan 1, 2012 9:00PM"
t.save!
t.hold_until
=> Sun, 01 Jan 2012 16:00:00 EST -05:00
# notice the above time lost 5 hours
问题是该字符串来自用户提供的POST请求。假设用户输入是在本地时间而不是UTC,这是不是最有意义。我错过了什么或不应该是ActiveRecord的默认值?除了必须在所有控制器中转换时间之外,有什么方法可以做到这一点。这似乎是错误的,而且不是很干。
答案 0 :(得分:0)
我想出了这个问题,它与ActiveRecord中写得不好的代码有关(惊喜!)。无论如何,ActiveRecord :: Base.define_attribute_methods通过方法丢失来调用懒惰。我有这样定义的方法:
def hold_until=(value)
# do some stuff here
super
end
所以ActiveRecord正在跳过那个认为它被定义的方法。它应该没关系,但由于设计不佳,它确实如此。 AR有多种不同的方法可以根据列类型定义方法。调用超级步骤并直接进入一般的“write_attribute”调用。唯一的解决方案是自己转换时间。由于所有alias_method_chain废话,因此在包含模块之前无法调用define_attribute_methods。而且你不能利用他们已经编写的代码,因为它在class_eval块中。如果可能的话,我会推荐datamapper。