Add a sort order to represent "staleness"

This commit is contained in:
Kevin McConnell
2025-03-27 09:44:43 +00:00
parent 4edbe8fe93
commit 47156c42e0
5 changed files with 38 additions and 2 deletions
+1
View File
@@ -20,6 +20,7 @@ class Bubble < ApplicationRecord
scope :indexed_by, ->(index) do
case index
when "most_active" then ordered_by_activity
when "most_stale" then ordered_by_staleness
when "most_discussed" then ordered_by_comments
when "most_boosted" then ordered_by_boosts
when "newest" then reverse_chronologically
+7
View File
@@ -5,6 +5,13 @@ module Bubble::Scorable
included do
scope :ordered_by_activity, -> { order activity_score_order: :desc }
# Staleness is measured by the amount of activity_score lost since it was last updated.
# The factor 0.9 is chosen to make the decay curve closer to linear; an exponential
# curve would make recent items appear stale very quickly, due to the sharp dropoff.
scope :ordered_by_staleness, -> { order Arel.sql(
"coalesce(activity_score * (1 - power(0.9, julianday('now') - julianday(activity_score_at))), 0) desc"
) }
end
def rescore
+1 -1
View File
@@ -1,7 +1,7 @@
module Filter::Fields
extend ActiveSupport::Concern
INDEXES = %w[ most_discussed most_boosted newest oldest popped ]
INDEXES = %w[ most_discussed most_boosted most_stale newest oldest popped ]
delegate :default_value?, to: :class
+26 -1
View File
@@ -50,7 +50,32 @@ class Bubble::ScorableTest < ActiveSupport::TestCase
travel_back
bubble_new.boost!
assert_equal [ bubble_new, bubble_mid, bubble_old ], Bubble.where(id: [ bubble_old, bubble_mid, bubble_new ]).ordered_by_activity
assert_equal %w[ new mid old ], Bubble.where(id: [ bubble_old, bubble_mid, bubble_new ]).ordered_by_activity.map(&:title)
end
end
test "items with old activity are more stale than those with none, or with new activity" do
with_current_user :kevin do
travel_to 20.days.ago
bubble_old = buckets(:writebook).bubbles.create! status: :published, title: "old"
bubble_new = buckets(:writebook).bubbles.create! status: :published, title: "new"
bubble_none = buckets(:writebook).bubbles.create! status: :published, title: "none"
bubble_old.boost!
bubble_old.boost!
travel_back
travel_to 2.days.ago
bubble_new.boost!
bubble_new.boost!
travel_back
assert_equal %w[ old new none ], Bubble.where(id: [ bubble_none, bubble_old, bubble_new ]).ordered_by_staleness.map(&:title)
bubble_old.boost!
assert_equal %w[ new old none ], Bubble.where(id: [ bubble_none, bubble_old, bubble_new ]).ordered_by_staleness.map(&:title)
end
end
+3
View File
@@ -110,6 +110,9 @@ class FilterTest < ActiveSupport::TestCase
filters(:jz_assignments).update!(stages: [], assignees: [], tags: [], buckets: [ buckets(:writebook) ])
assert_equal "Most discussed in Writebook", filters(:jz_assignments).summary
filters(:jz_assignments).update!(indexed_by: "most_stale")
assert_equal "Most stale in Writebook", filters(:jz_assignments).summary
end
test "params without a key-value pair" do