mirror of
https://github.com/discourse/discourse.git
synced 2026-08-08 17:53:55 +08:00
<img width="667" height="325" alt="Screenshot 2026-07-28 at 11 57 10" src="https://github.com/user-attachments/assets/b58efdbb-7158-4c92-a83f-b1a484769993" /> <img width="538" height="347" alt="Screenshot 2026-07-28 at 11 57 22" src="https://github.com/user-attachments/assets/65ffbea6-8e7e-49cd-b49f-599b8a50b7da" />
82 lines
1.9 KiB
Ruby
Vendored
82 lines
1.9 KiB
Ruby
Vendored
# frozen_string_literal: true
|
|
|
|
module DiscourseTopicVoting
|
|
module Votes
|
|
class Cast
|
|
include Service::Base
|
|
|
|
params do
|
|
attribute :topic_id, :integer
|
|
|
|
validates :topic_id, presence: true
|
|
end
|
|
|
|
model :topic
|
|
|
|
policy :can_see_topic
|
|
policy :topic_is_votable
|
|
policy :topic_not_already_voted
|
|
policy :current_user_can_vote
|
|
|
|
transaction do
|
|
model :vote, :create_vote
|
|
step :refresh_vote_count
|
|
end
|
|
|
|
step :enqueue_backfill_badges
|
|
step :enqueue_topic_upvote_webhook
|
|
step :publish_vote_created_event
|
|
|
|
private
|
|
|
|
def fetch_topic(params:)
|
|
Topic.find_by(id: params.topic_id)
|
|
end
|
|
|
|
def can_see_topic(guardian:, topic:)
|
|
guardian.can_see?(topic)
|
|
end
|
|
|
|
def topic_is_votable(topic:)
|
|
topic.can_vote?
|
|
end
|
|
|
|
def topic_not_already_voted(guardian:, topic:)
|
|
!topic.user_voted?(guardian.user)
|
|
end
|
|
|
|
def current_user_can_vote(guardian:)
|
|
guardian.user.can_vote?
|
|
end
|
|
|
|
def create_vote(guardian:, topic:)
|
|
DiscourseTopicVoting::Vote.create!(user: guardian.user, topic: topic)
|
|
end
|
|
|
|
def refresh_vote_count(topic:)
|
|
topic.update_vote_count
|
|
end
|
|
|
|
def enqueue_backfill_badges(topic:)
|
|
Jobs.enqueue(Jobs::DiscourseTopicVoting::BackfillBadges, topic_id: topic.id)
|
|
end
|
|
|
|
def enqueue_topic_upvote_webhook(guardian:, topic:)
|
|
return if !WebHook.active_web_hooks(:topic_upvote).exists?
|
|
|
|
payload = {
|
|
topic_id: topic.id,
|
|
topic_slug: topic.slug,
|
|
voter_id: guardian.user.id,
|
|
vote_count: topic.vote_count,
|
|
}
|
|
|
|
WebHook.enqueue_topic_voting_hooks(:topic_upvote, topic, payload.to_json)
|
|
end
|
|
|
|
def publish_vote_created_event(vote:)
|
|
DiscourseEvent.trigger(:topic_voting_vote_created, vote)
|
|
end
|
|
end
|
|
end
|
|
end
|