处理模型表中 expires_in 数据的最佳方法是啥
Posted
技术标签:
【中文标题】处理模型表中 expires_in 数据的最佳方法是啥【英文标题】:What is the best way to handle expires_in data in the model table处理模型表中 expires_in 数据的最佳方法是什么 【发布时间】:2021-11-14 12:06:16 【问题描述】:我有已购买的许可证,并成为用户在购买许可证时获得的 user_licenses。许可证的有效期、费用、名称和描述都存储在许可证表中。
购买许可证时,在 user_license 上设置到期时间(Date.now + License.expiration_years)
所以基本上用户许可到期日期是:
UserLicense.expiration_date = Date.now + expires_in_days.days + expires_in_weeks.weeks + expires_in_months.months + expires_in_years.years
还有其他方法可以处理expire_in_*
列吗?也许使用某种 jsonb 结构?
# license table:
t.string :name, null: false
t.string :description
t.integer :amount, default: 0, null: false
t.jsonb :details, default: , null: false
t.boolean :hidden
t.string :currency
t.integer :expires_in_days, default: 0, null: false
t.integer :expires_in_weeks, default: 0, null: false
t.integer :expires_in_months, default: 0, null: false
t.integer :expires_in_years, default: 0, null: false
【问题讨论】:
到期日是现在+年,还是现在+天+周……计算?仅存储日期对我来说似乎要简单得多。 @Andrew 是的,user_license 到期的计算基于许可证expire_in_*
(expires_in_days, expires_in_weeks...)。不能只存储日期,因为它是到期日期的日期范围。而且真的没有办法在一个字段中存储包含天、周和月的时间范围,因为它不是日期。
【参考方案1】:
使用 Postgres interval type。此类型表示持续时间,例如:
INTERVAL '1 year 2 months 3 days'
Rails 支持the interval type natively since 6.1 并将其映射到ActiveSupport::Duration。您可以在以前的版本中使用它,但您需要手动解析字符串。如果你想提前一个日期,你可以使用Time#advance:
# Three days, four hours and 30 minutes
Time.current.advance(
ActiveSupport::Duration.parse("P3DT4H30M").parts
)
不仅如此,您还可以使用间隔以相对时间进行数据库查询而不会发疯。
【讨论】:
【参考方案2】:正如在其他 cmets 中已经说明的那样,除非问题中没有提到在数据库中存储特定天/周/月/年以供将来到期的正当理由,否则您只需存储到期日期即可避免很多麻烦.
然后从这个日期开始,你可以计算任何你想要的。
【讨论】:
这个问题有点令人困惑,但我想我已经弄清楚了。单个许可证的实际到期日期存储在user_license
表中,而licenses
存储如果您今天购买许可证的持续时间间隔 - 例如。您购买的是 6 个月或 1 年的联系人。这就是为什么简单的日期行不通的原因。以上是关于处理模型表中 expires_in 数据的最佳方法是啥的主要内容,如果未能解决你的问题,请参考以下文章
在laravel中将虚拟数据添加到“联接表”的最佳方法是什么?
从 yii 中的模型获取相关数据并返回 json 的最佳方法