如何为Coupons表创建含当前日期条件的唯一索引?
解决Coupons表活跃优惠券code唯一索引的问题
你遇到的核心问题是迁移代码里用了Time.now.utc,这会把迁移执行时的时间硬编码到索引中,无法实现每次验证时使用当前动态时间。正确的做法是使用数据库内置的当前时间函数,让索引在每次校验时自动获取当前时间。
核心逻辑梳理
活跃优惠券的判定条件:
- status 不等于归档状态(你代码中用
status <> 2,确认2对应'archived'即可) - expiration_date 为空,或者 expiration_date 晚于当前时间(未过期)
按数据库类型编写迁移代码
PostgreSQL 环境
add_index :coupons, :code, where: "status <> 2 AND (expiration_date IS NULL OR expiration_date > CURRENT_TIMESTAMP)", unique: true, name: 'index_unique_coupon_code'
MySQL 8.0+ 环境
add_index :coupons, :code, where: "status <> 2 AND (expiration_date IS NULL OR expiration_date > NOW())", unique: true, name: 'index_unique_coupon_code'
关键说明
- 用数据库内置的
CURRENT_TIMESTAMP(PostgreSQL)或NOW()(MySQL),替代Ruby的Time.now.utc,确保每次索引校验时都使用动态的当前时间 - 调整过期判断逻辑:从
expiration_date <= ?改为expiration_date > 当前时间,符合你对“活跃优惠券未过期”的定义 - 如果status是字符串类型(直接存储'archived'),把条件改成
status != 'archived'即可
内容的提问来源于stack exchange,提问作者ZimZimma
相关产品推荐
相关产品推荐

