2016-12-26 30 views
0

我想用Mysql 5.6.33和mysql2 gem 0.4.5将我的项目升级到ActiveRecord 5.0.1。我有许多规格测试涉及创建一条记录,然后搜索created_at值为<= Time.now的记录。我总结了失败与行为改变的下面的示例ActiveRecord的4.2到5.0.1的ActiveRecord:ActiveRecord 4.2到5.0.1日期时间精度行为变化

ActiveRecord的4

irb(main):021:0> puts Time.at(1482722443.8581448) 
2016-12-26 03:20:43 +0000 
=> nil 
irb(main):022:0> p.updated_at = Time.at(1482722443.8581448) 
=> 2016-12-26 03:20:43 +0000 
irb(main):023:0> p.save 
=> true 
irb(main):024:0> p.updated_at 
=> 2016-12-26 03:20:43 UTC 
irb(main):025:0> p.reload 
=> #<Profile id: 1, ... 
irb(main):026:0> p.updated_at 
=> 2016-12-26 03:20:43 UTC 

的ActiveRecord 5.0.1

> puts Time.at(1482722443.8581448) 
2016-12-26 03:20:43 +0000 
=> nil 
> p.updated_at = Time.at(1482722443.8581448) 
=> 2016-12-26 03:20:43 +0000 
> p.save 
=> true 
> p.updated_at 
=> 2016-12-26 03:20:43 UTC 
> p.reload 
=> #<Profile:0x0055e04486dc40 
id: 1, 
... 
> p.updated_at 
=> 2016-12-26 03:20:44 UTC 

如您所见,在AR4的第一个示例中,数据库返回的日期时间为43秒,因此它将执行floor操作在提供的时间戳1482722443.8581448上。

在AR5,它是做一个round操作,并且移动所述created_at时间成为下一个整个第二,由此使得从第二43到第二44

这导致记录被创建“在未来“,以及我创建的例子,然后搜索created_at<= Time.now的记录没有返回任何记录,因为它几乎毫秒级地创造了未来。

这是行为预期,还是这是一个错误?我可以在AR5中配置毫秒舍入行为吗?

UPDATE

它看起来像MySQL中如果我这样做:

update alerts set created_at = '2016-12-26 04:08:19.7777' limit 1;

然后:

select created_at from alerts;

我得到

2016-12-26 04:08:20

因此,mysql正在做“收尾”。有没有可能,从4.2到5.0.1,ActiveRecord的开始编写查询以日期时间为

2016-12-26 04:08:19.7777

而不是

2016-12-26 04:08:19

与MySQL 33年6月5日?

回答

0

是的,ActiveRecord 5已经根据this blog post更改了其行为。

以下是在ActiveRecord 5.0.1中添加此支持的twocommits

要恢复以前的行为,我不得不添加以下猴补丁:

module ActiveRecord 
    module ConnectionAdapters 
    class AbstractMysqlAdapter < AbstractAdapter 
    end 
    class Mysql2Adapter < AbstractMysqlAdapter 
     def supports_datetime_with_precision? 
     false 
     end 
    end 
    end 
end