I’ve made some good progress on the design spike of this feature over the last week. I’m working in this branch (which I force push to frequently) if you want to follow along:
https://github.com/discourse/discourse/tree/reviewable
Current Design
The current design is you have a Reviewable
model, which uses Rails’ Single Table Inheritance. If you have a thing you want to be added to the review queue, you create a model for it that extends Reviewable
. For example a ReviewableUser
would represent a User
that needs review.
Each Reviewable
has a polymorphic association called target
. For a ReviewableUser
you’d set it to be the User
you want reviewed:
reviewable = ReviewableUser.needs_review!(target: user, created_by: current_user)`
You can then establish the actions
that can be performed on a ReviewableUser
:
class ReviewableUser < Reviewable
def build_actions(actions, guardian)
return unless pending?
actions.add(:approve) if guardian.can_approve?(target)
actions.add(:reject) if guardian.can_delete_user?(target)
end
def perform_approve(performed_by)
target.approved = true
target.approved_by ||= approved_by
target.approved_at ||= Time.zone.now
target.save!
PerformResult.new(:success, transition_to: :approved)
end
def perform_reject(performed_by)
destroyer = UserDestroyer.new(performed_by)
destroyer.destroy(target)
PerformResult.new(:success, transition_to: :rejected)
rescue UserDestroyer::PostsExistError
PerformResult.new(:failed)
end
end
A few notes about actions:
-
They can be built based on the user requesting their list of stuff to review. So it’s easy to add logic that says only certain user types (admins? in a group?).
-
The UI will build buttons for those actions. When selected, the call will delegate to the
perform_#{action_id}
method to do the thing. The results of operations can be success/failure, and can optionally return a new state for the reviewable. So in the code above, theperform_approve
action handler will transition the reviewable toapproved
when complete.
More Fun Stuff
-
Reviewable content has its own system for choose who can see it. You can restrict a reviewable to be shown only do admins, to moderators, or to a particular group.
-
I am building in the ability to “claim” a reviewable. Claiming topics for moderation currently works via the discourse-assign plugin but it’s very awkward and buggy. Most people probably won’t use it but having the ability to do at a row level will help a lot.