I have a notifications table in my database which contains the attributes: timestamp:datetime
and read:boolean
. What I want is to query and order my notifications; first by if they are read or not, then after which timestamp they've got, then limit the amount of notifications to 10.
The query I've tried looks something like this:
@user.notifications.order_by([[:read,:desc],[:timestamp,:desc]]).limit(10)
Which only gives me an error which I narrowed down to proving the boolean field as the culprit.
Is there an existing way of ordering by true/false values or should I resort to using some kind of Custom Field Serialization transforming True's and False's to 1's and 0's?
What you specify works for me with Mongoid 2.4.10, mongo 1.3, rails 3.2.3. Hope that the following helps to address your problem.
class User
include Mongoid::Document
field :name, type: String
has_many :notifications
end
class Notification
include Mongoid::Document
field :read, type: Boolean
field :timestamp, type: DateTime
belongs_to :user
end
test/unit/notification_test.rb
require 'test_helper'
class NotificationTest < ActiveSupport::TestCase
def setup
User.delete_all
Notification.delete_all
end
test "order_by boolean" do
@user = User.create(name: 'Gary')
[
[true, 1.day.ago], [false, 2.days.ago], [false, 3.days.ago], [true, 5.days.ago], [false, 8.days.ago], [true, 11.days.ago],
[false, 4.days.ago], [true, 6.days.ago], [true, 7.days.ago], [false, 9.days.ago], [false, 10.days.ago]
].each do |read, timestamp|
@user.notifications << Notification.create(read: read, timestamp: timestamp)
end
assert_equal(1, User.count)
assert_equal(11, Notification.count)
result = @user.notifications.order_by([[:read,:desc],[:timestamp,:desc]]).limit(10).to_a
assert_equal(10, result.size)
result.each do |r|
p [r.read, r.timestamp]
end
end
end
test output
Run options: --name=test_order_by_boolean
# Running tests:
[true, Mon, 28 May 2012 12:33:49 -0400]
[true, Thu, 24 May 2012 12:33:49 -0400]
[true, Wed, 23 May 2012 12:33:49 -0400]
[true, Tue, 22 May 2012 12:33:49 -0400]
[true, Fri, 18 May 2012 12:33:49 -0400]
[false, Sun, 27 May 2012 12:33:49 -0400]
[false, Sat, 26 May 2012 12:33:49 -0400]
[false, Fri, 25 May 2012 12:33:49 -0400]
[false, Mon, 21 May 2012 12:33:49 -0400]
[false, Sun, 20 May 2012 12:33:49 -0400]
.
Finished tests in 0.023062s, 43.3614 tests/s, 130.0841 assertions/s.
1 tests, 3 assertions, 0 failures, 0 errors, 0 skips