Active Record 零时间戳

Active Record nil timestamp

我创建了一个 table,如下所示。

CREATE TABLE foo(
  id INT PRIMARY KEY AUTO_INCREMENT,
  num INT,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  updated_at TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);

在我插入并编辑一些值后,我得到下面的 table。

+----+------+---------------------+---------------------+
| id | num  | created_at          | updated_at          |
+----+------+---------------------+---------------------+
|  1 |   15 | 2020-06-22 11:19:56 | 2020-06-22 11:20:20 |
|  2 |   13 | 2020-06-22 11:19:58 | 0000-00-00 00:00:00 |
|  3 |   14 | 2020-06-22 11:20:01 | 0000-00-00 00:00:00 |
+----+------+---------------------+---------------------+

然后我有 class:

require 'active_record'

class Foo < ActiveRecord::Base
  self.table_name = 'foo'
end
1 Foo.all # => [#<Foo:0x000056314a734188 id: 1, num: 15, created_at: 2020-06-22 11:23:40 UTC, updated_at: 2020-06-22 11:23:48 UTC>, #<Foo:0x000056314a7340c0 id: 2, num: 13, created_at: 2020-06-22 11:23:43 UTC, updated_at: nil>, #<Foo:0x000056314a743f98 id: 3, num: 14, created_at: 2020-06-22 11:23:46 UTC, updated_at: nil>]

2 Foo.where(updated_at: nil) # => []

3 Foo.where.not(updated_at: nil) # => [#<Foo:0x000055aafe3ba6d8 id: 1, num: 15, created_at: 2020-06-22 11:23:40 UTC>, #<Foo:0x000055aafe3ba5e8 id: 2, num: 13, created_at: 2020-06-22 11:23:43 UTC>, #<Foo:0x000055aafe3ba520 id: 3, num: 14, created_at: 2020-06-22 11:23:46 UTC>]

4 Foo.where(updated_at: '0000-00-00 00:00:00') # => []

5 Foo.where.not(updated_at: '0000-00-00 00:00:00') # => []

6 Foo.where("updated_at = '0000-00-00 00:00:00'") # => [#<Foo:0x000056314a8857d0 id: 2, num: 13, created_at: 2020-06-22 11:23:43 UTC, updated_at: nil>, #<Foo:0x000056314a885708 id: 3, num: 14, created_at: 2020-06-22 11:23:46 UTC, updated_at: nil>]

7 Foo.where("updated_at != '0000-00-00 00:00:00'") # => [#<Foo:0x000056314a8d7878 id: 1, num: 15, created_at: 2020-06-22 11:23:40 UTC, updated_at: 2020-06-22 11:23:48 UTC>]
+------------------------------------------------------------------------------------------------------------------------------+
| @@global.sql_mode                                                                                                            |
+------------------------------------------------------------------------------------------------------------------------------+
| ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |
+------------------------------------------------------------------------------------------------------------------------------+

+------------------------------------------------------------------------------------------------------------------------------+
| @@session.sql_mode                                                                                                           |
+------------------------------------------------------------------------------------------------------------------------------+
| ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |
+------------------------------------------------------------------------------------------------------------------------------+

+-------------------------+
| @@version               |
+-------------------------+
| 5.7.30-0ubuntu0.18.04.1 |
+-------------------------+

我的问题

  1. 当时间戳为 0000-00-00 00:00:00 时,您得到 nils 是正常行为吗?
  2. 为什么第 4 行和第 5 行的代码没有按预期工作?

您应该让 ActiveRecord 为您处理这些更新。您不需要使用迁移,只需让列没有任何默认值即可。

CREATE TABLE foo(
  id INT PRIMARY KEY AUTO_INCREMENT,
  num INT,
  created_at TIMESTAMP NOT NULL,
  updated_at TIMESTAMP NOT NULL
);

然后 ActiveRecord 将在保存和更新时自动填充这些值。