Hey guys. I have a model, Item, which is set to “expire” in created_at + 100.days. I am trying to create a scope that will return the items which will expire in a supplied time, such as 10.days.
So far I have this:
scope :expires_within, lambda {|time| where("created_at > ?", time)}
So that I could eventually do something like:
Item.expires_within(10.days)
Which would return a collection of items which expire within 10 days.
This isn’t right, I just wanted to have a skeleton of what I should have. I can’t figure out if it’s possible to do this through a scope or not. It seems to me like I would be able to if I had a column in the table called expires_at, but the problem is that I would rather not create such a column because I want the expiration time, above stated as created_at + 100.days, to be flexible.
I just wanted to see if it would be possible without such a column, or if it can be done but not with a scope, I’d like to hear that possibility as well. If not, I’ll go ahead and add it.
I have come up with a solution I believe. I will continue to test it.
Basically my original formula to calculate whether something was expired was:
Since I want to determine whether something expires within a future time (e.g. 10.days), I add it to the left-hand side:
Remember, 100.days is how long an item has to live before it expires.
Finally, I solve for
created_atso that it’s by itself, since that’s what the sql query demands, by subtracting100.daysfrom the other side:This could be made more concise, as Ryan pointed out, by doing:
Basic math I guess. I’m still pretty dazed from thinking about it too hard, so I will test it a bit to make sure it works as intended. If it does,
Item.expires_within(10.days)should return a collection of items which will expire within 10 days (or before).EDIT: I’ve refactored this to ignore the items which have already expired. So the new scope looks for the items that have not yet expired and will expire within a specified time frame: