Rails记录神秘冻结,默默地丢弃了upates

Leo*_*ons 9 postgresql ruby-on-rails

我有一个带users桌子的Rails应用程序.PostgreSQL是数据库.出于某种原因,对其中一个用户记录的所有更新都会成功,然后以静默方式还原.到底是怎么回事?

破碎:

> u = User.find_by(username: 'alice')
> u.last_access
=> Thu, 19 Jul 2018 17:59:35 UTC +00:00
> u.last_access -= 20.days
=> Fri, 29 Jun 2018 17:59:35 UTC +00:00
> u.save!
   (1.6ms)  BEGIN
...
  User Update (1.4ms)  UPDATE "users" SET "updated_at" = $1, "last_access" = $2 WHERE "users"."id" = $3  [["updated_at", "2019-01-14 19:02:56.271382"], ["last_access", "2018-06-29 17:59:35"], ["id", 1]]
   (0.8ms)  COMMIT
=> true
> reload!
> User.find_by(username: 'alice').last_access
=> Thu, 19 Jul 2018 17:59:35 UTC +00:00

> # WHY NOT 29 JUN???
Run Code Online (Sandbox Code Playgroud)

相同的操作适用于不同的用户:

> u = User.find_by(username: 'bob')
> u.last_access
=> Mon, 24 Dec 2018 03:33:47 UTC +00:00
> u.last_access -= 20.days
=> Tue, 04 Dec 2018 03:33:47 UTC +00:00
> u.save!
   (1.8ms)  BEGIN
...
  User Update (6.3ms)  UPDATE "users" SET "updated_at" = $1, "last_access" = $2 WHERE "users"."id" = $3  [["updated_at", "2019-01-14 18:59:56.087223"], ["last_access", "2018-12-04 03:33:47"], ["id", 2]]
   (2.0ms)  COMMIT
=> true
> reload!
> User.find_by(username: 'bob').last_access
=> Tue, 04 Dec 2018 03:33:47 UTC +00:00

> # GOOD
Run Code Online (Sandbox Code Playgroud)

我正在使用paper_trail gem进行版本控制,但我找不到任何用于冻结该gem中的对象的功能.

paper_trail配置为忽略last_access列:

has_paper_trail ignore: %i[created_at last_access last_login updated_at]
Run Code Online (Sandbox Code Playgroud)

该列上有一个PostgreSQL索引:

t.index ["last_access", "last_login"], name: "index_users_on_last_access_and_last_login", using: :btree
Run Code Online (Sandbox Code Playgroud)

在ActiveRecord中未冻结用户记录损坏:

> User.find_by(username: 'alice').frozen?
=> false
Run Code Online (Sandbox Code Playgroud)

tpe*_*ett 6

如果直接对数据库执行更新,更改是否会生效?例如,你可以这样做:

User.connection.execute 'UPDATE "users" SET "last_access" = \'2018-12-04 03:33:47\' WHERE username = 'alice'
Run Code Online (Sandbox Code Playgroud)

如果更改在此时没有生效,那么我会怀疑数据库中有触发器或某些东西导致奇怪的行为.


编辑:

我很奇怪您的日志显示Rails成功更新但记录实际上没有被更改.我仍然不相信数据库中没有发生任何事情.

尝试对该表执行模式转储,并仔细查看可能导致值从您下面更改的任何触发器.

pg_dump -t 'public.users' --schema-only DB_NAME
Run Code Online (Sandbox Code Playgroud)