DateAsBool is a simple Rails Gem to get both a datetime and a boolean behaviour from the same database column.
Add this line to your application's Gemfile:
gem 'date_as_bool'
And then execute:
$ bundle
Or install it yourself as:
$ gem install date_as_bool
Let's say you have a users
table with column verified_at:datetime
.
Add
class User < ApplicationRecord
date_as_bool :verified_at
...
Now you can use user.verified
or user.verified?
to test for verified_at
presence, and user.verified!
as an alias for user.update(verified_at: Time.now)
.
You can change the field with user.update(verified: bool)
. If false, it resets verified_at
to nil
, if true, it sets it to Time.now
.
You also get the scopes User.verified
, equivalent to User.where.not(verified_at: nil)
, and User.not_verified
equivalent to User.where(verified_at: nil)
.
User.verified == User.where.not(verified_at: nil)
User.not_verified == User.where(verified_at: nil)
user.verified == user.verified_at.present?
user.verified? == user.verified_at.present?
user.verified! == user.update(verified: true) == user.update(verified_at: Time.now)
user.update(verified: false) == user.update(verified_at: nil)
Often, when you need a boolean flag on a model, you can accomplish more by using a datetime attribute instead, that captures the first time the flag turned on. But to recover the simplicity of dealing with a boolean instead of a datetime you have to write some lines of code.
So, I found myself quite often with the following design pattern:
# == Schema Information
#
# Table name: users
#
# id :integer not null, primary key
# verified_at :datetime
# ...
#
class User < ApplicationRecord
scope :verified, -> { where.not(verified_at: nil) }
scope :not_verified, -> { where(verified_at: nil) }
def verified=(bool)
self.verified_at = bool ? Time.now : nil
end
def verified
verified_at.present?
end
alias verified? verified
def verified!
verified = true
save
end
# ...
end
This way, I can both use User.verified
and User.where(verified_at: 2.days.ago..Time.now)
.
DateAsBool abstracts this behaviour in one line.
If you want to give a different name to the boolean method, you can specify it as the second argument.
date_as_bool :verified_at
is just a shortcut for date_as_bool :verified_at, :verified
.
Bug reports and pull requests are greatly appreciated.
The gem is available as open source under the terms of the MIT License.