Rails 在 created_at 年添加索引
Rails add index on year of created_at
在我的 Rails 应用程序中,我有一张模型票。它的 created_at
字段 ActiveSupport::TimeWithZone
。它还有一个整数类型的 number
字段。 number
字段不是主键。主键是一个 UUID。
任何一年,我都不能有2张相同号码的票。例如,在 2020 年,不允许有 2 张编号为 15 的工单。但是,如果它们是在不同年份创建的,则允许 2 张工单具有相同的编号。例如,2019 年创建的工单编号为 15,2020 年创建的工单编号为 15 --- 可以。
所以我试图在 table 的门票 created_at 的编号和年份上添加索引,并要求索引是唯一的:
class AddIndexToTickets < ActiveRecord::Migration[5.2]
def change
add_index :tickets, "number,(created_at.year)", unique: true, name: 'index_tickets_uniqueness'
end
end
这会导致错误
PG::UndefinedTable: ERROR: missing FROM-clause entry for table "created_at"
LINE 1: ..." ON "tickets" (number,(created_at...
这样做的原因是为了避免并发问题。在我的代码中,我有每次创建新票证时自动递增 number
的机制。它在大部分时间都有效。但是,如果创建的两张门票彼此非常接近,这将成为一个问题。
我该怎么办?我认为,自定义验证也可能会失败,具体取决于确切的时间。
谢谢!
你试图使用 Ruby 语法,而你应该使用 PostgreSQL 语法。调用 created_at.date
将在 Ruby ActiveSupport::TimeWithZone
对象上工作,但是您传递给 add_index
的参数将由 Postgres 计算,而不是 Ruby。所以它失败了,因为对于 Postgres,created_at.date
在这里是无效的语法。所以要修复它,你只需要切换到 PostgreSQL 语法。
我认为你可以通过这样的方式实现你想要的:
add_index :tickets, "number, EXTRACT(YEAR FROM created_at)", unique: true, name: 'index_tickets_uniqueness_on_year'.
未经测试,但应该可以。 More info on the EXTRACT function and other Postgres Date/Time stuff here.
在我的 Rails 应用程序中,我有一张模型票。它的 created_at
字段 ActiveSupport::TimeWithZone
。它还有一个整数类型的 number
字段。 number
字段不是主键。主键是一个 UUID。
任何一年,我都不能有2张相同号码的票。例如,在 2020 年,不允许有 2 张编号为 15 的工单。但是,如果它们是在不同年份创建的,则允许 2 张工单具有相同的编号。例如,2019 年创建的工单编号为 15,2020 年创建的工单编号为 15 --- 可以。
所以我试图在 table 的门票 created_at 的编号和年份上添加索引,并要求索引是唯一的:
class AddIndexToTickets < ActiveRecord::Migration[5.2]
def change
add_index :tickets, "number,(created_at.year)", unique: true, name: 'index_tickets_uniqueness'
end
end
这会导致错误
PG::UndefinedTable: ERROR: missing FROM-clause entry for table "created_at"
LINE 1: ..." ON "tickets" (number,(created_at...
这样做的原因是为了避免并发问题。在我的代码中,我有每次创建新票证时自动递增 number
的机制。它在大部分时间都有效。但是,如果创建的两张门票彼此非常接近,这将成为一个问题。
我该怎么办?我认为,自定义验证也可能会失败,具体取决于确切的时间。
谢谢!
你试图使用 Ruby 语法,而你应该使用 PostgreSQL 语法。调用 created_at.date
将在 Ruby ActiveSupport::TimeWithZone
对象上工作,但是您传递给 add_index
的参数将由 Postgres 计算,而不是 Ruby。所以它失败了,因为对于 Postgres,created_at.date
在这里是无效的语法。所以要修复它,你只需要切换到 PostgreSQL 语法。
我认为你可以通过这样的方式实现你想要的:
add_index :tickets, "number, EXTRACT(YEAR FROM created_at)", unique: true, name: 'index_tickets_uniqueness_on_year'.
未经测试,但应该可以。 More info on the EXTRACT function and other Postgres Date/Time stuff here.