Rails 7竞赛应用中acts_as_votable多阶段投票重置问题求助
解决Rails 7竞赛应用分阶段独立投票的问题
核心思路
acts_as_votable默认只关联投票者与被投票项目,没有「竞赛阶段」的隔离维度,导致不同阶段的投票数据混在一起。解决关键是给每一票绑定对应的竞赛阶段,实现各阶段投票数据的独立存储与统计。
具体实现步骤
1. 扩展默认Vote模型
先给投票表添加竞赛阶段关联字段:
# 生成迁移文件 rails generate migration AddCompetitionStageIdToVotes competition_stage:references rails db:migrate
修改Vote模型,关联竞赛阶段:
# app/models/vote.rb class Vote < ActsAsVotable::Vote belongs_to :competition_stage, optional: true end
2. 调整投票逻辑
投票时必须指定当前竞赛阶段,同时避免用户同一阶段重复投票:
# 项目控制器的投票动作示例 def vote @project = Project.find(params[:id]) @current_stage = CompetitionStage.find(params[:stage_id]) existing_vote = Vote.find_by(voter: current_user, votable: @project, competition_stage: @current_stage) if existing_vote existing_vote.destroy # 取消已投的票 else @project.votes.create(voter: current_user, competition_stage: @current_stage) end redirect_to @project end
3. 统计指定阶段的票数
在项目模型中添加方法,专门统计某一阶段的票数:
# app/models/project.rb class Project < ApplicationRecord acts_as_votable def stage_votes_count(stage) votes.where(competition_stage: stage).count end end # 视图中调用示例 <%= @project.stage_votes_count(@current_stage) %>
4. 阶段投票重置
当需要重置某阶段的投票时,直接删除该阶段下的所有投票记录:
# app/models/competition_stage.rb class CompetitionStage < ApplicationRecord def reset_all_votes Vote.where(competition_stage: self).destroy_all end end
替代方案:独立创建阶段投票模型
如果不想修改默认Vote模型,可以单独构建StageVote模型实现隔离:
# 生成模型及迁移 rails generate model StageVote user:references project:references competition_stage:references rails db:migrate # 关联模型 class Project < ApplicationRecord has_many :stage_votes end class CompetitionStage < ApplicationRecord has_many :stage_votes end # 投票逻辑示例 def vote @project = Project.find(params[:id]) @current_stage = CompetitionStage.find(params[:stage_id]) StageVote.find_or_create_by(user: current_user, project: @project, competition_stage: @current_stage) end # 统计票数 @project.stage_votes.where(competition_stage: @current_stage).count
内容的提问来源于stack exchange,提问作者Lepa Malomalo
相关产品推荐
相关产品推荐

