I spent an insane amount of time trying to figure out how to elegantly compare attributes belonging to the same document and stumbled upon a few stackoverflow questions that helped. However the solution still doesn’t appear elegant enough but does the job.
scope :expired, any_of({:completed_date.ne => nil}, {:expiry_date.lte => Date.today.to_time}, {:usage_count => {"$gte" => "this.max_usage_count"}})
Certainly not noteworthy but this post is to help me document this bit.
Goal
To build a named scope to allow me to query expired documents. The model has the following fields
field :code, :type => String field :allowed_domain, :type => Integer, :default => DOMAIN_ALL_SITES field :description, :type => String field :discount_type, :type => Integer, :default => PERCENTAGE_DISCOUNT field :dollar_discount_cents, :type => Integer, :default => 0 field :percentage_discount, :type => Integer, :default => 0 field :max_usage_count, :type => Integer, :default => 1 field :usage_count, :type => Integer, :default => 0 field :expiry_date, :type => DateTime, :default => (DateTime.now + 1.week) field :completed_date, :type => DateTime index :code index :expiry_date index :allowed_domain
The precondition for an expired record is that its completed_date
should be nil
, the expiry_date
should be less than the present date and usage_count
must be less than the max_usage_count
While the above block of code does that, what I hate is the mixing JSON and Ruby. While mongoid for most purposes does a good job in making life easier (as every ORM should), there are occasions where I’d prefer it let me write pure Mongodb queries or use the Ruby wrappers entirely.
Other Resources
http://stackoverflow.com/questions/3795044/mongoid-named-scope-comparing-two-time-fields-in-the-same-document
Further bulletins as events warrant.