I have licenses that are purchased and become user_licenses that users get when they purchase the license. The time a license is valid for, cost, name and description are all stored in the license table.
When the license is purchased the expiration is set on the user_license (Date.now License.expiration_years)
So basically the user license expiration date is:
UserLicense.expiration_date = Date.now expires_in_days.days expires_in_weeks.weeks expires_in_months.months expires_in_years.years
Is there another way to handle the expire_in_*
columns? Maybe using a sort of jsonb structure?
# 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
CodePudding user response:
As already stated in other comments, unless there is a valid reason not mentioned in the question to store specific days/weeks/months/years for future expiration in the database, you avoid a lot of trouble by just storing the expiration date.
Then from this date you could calculate whatever you want.
CodePudding user response:
Use the Postgres interval type. This type represents a duration of time such as:
INTERVAL '1 year 2 months 3 days'
Rails has supported the interval type natively since 6.1 and maps it to an ActiveSupport::Duration. You can use it in previous versions but you need to manually parse the string. If you want to advance a date from a duration you can use Time#advance:
# Three days, four hours and 30 minutes
Time.current.advance(
ActiveSupport::Duration.parse("P3DT4H30M").parts
)
Not only that but you can also use intervals to do database queries with relative time without going insane.