forked from Trustie/forgeplus
76 lines
2.0 KiB
Ruby
76 lines
2.0 KiB
Ruby
class Vote < ApplicationRecord
|
|
self.table_name = 'new_votes'
|
|
|
|
belongs_to :platform_communicate
|
|
has_many :vote_options, dependent: :destroy
|
|
has_many :user_vote_options, through: :vote_options
|
|
|
|
accepts_nested_attributes_for :vote_options, allow_destroy: true
|
|
|
|
validates :max_choice_vote_options_count,
|
|
numericality: {
|
|
greater_than: 1,
|
|
less_than_or_equal_to: 20,
|
|
allow_nil: true
|
|
},
|
|
if: :is_multiple_choice?
|
|
|
|
validate :validate_multiple_choice_settings
|
|
|
|
|
|
def expired?
|
|
due_at.present? && due_at < Time.current
|
|
end
|
|
|
|
def user_voted?(user)
|
|
return false unless user
|
|
|
|
user_vote_options.where(user_id: user.id).exists?
|
|
end
|
|
|
|
def user_selections(user)
|
|
return UserVoteOption.none unless user
|
|
|
|
user_vote_options.where(user_id: user.id)
|
|
end
|
|
|
|
def total_votes_count
|
|
# 计算参与投票的总人数(去重)
|
|
user_vote_options.select(:user_id).distinct.count
|
|
end
|
|
|
|
def total_votes_options_count
|
|
vote_options.sum(:user_vote_options_count)
|
|
end
|
|
|
|
# 获取投票结果(使用缓存字段,性能更好)
|
|
def results_with_cache
|
|
vote_options.select(:id, :title, :user_vote_options_count).map do |option|
|
|
{
|
|
id: option.id,
|
|
title: option.title,
|
|
vote_count: option.user_vote_options_count,
|
|
percentage: calculate_percentage_for_option(option.user_vote_options_count)
|
|
}
|
|
end
|
|
end
|
|
|
|
private
|
|
|
|
def calculate_percentage_for_option(option_votes)
|
|
total = total_votes_options_count
|
|
return 0 if total.zero?
|
|
(option_votes.to_f / total * 100).round(2)
|
|
end
|
|
|
|
def validate_multiple_choice_settings
|
|
if is_multiple_choice? && max_choice_vote_options_count.nil?
|
|
errors.add(:max_choice_vote_options_count, '多选投票必须设置最大选择数')
|
|
end
|
|
|
|
if !is_multiple_choice? && max_choice_vote_options_count.present?
|
|
errors.add(:max_choice_vote_options_count, '单选投票不需要设置最大选择数')
|
|
end
|
|
end
|
|
end
|