You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rails使用acts_as_votable如何查询指定vote_scope的投票权重分值

Rails使用acts_as_votable实现多维度评分后查询用户打分值的方法

问题背景

我在Rails应用中使用acts_as_votable gem,为用户提供在不同维度下对资源进行1-5分评分的功能,比如用户可以对场馆的位置、价格等维度分别独立打出1-5分的评分。目前我已经实现了检查用户是否对指定维度完成投票的功能,但不知道如何同时查询用户此次投票对应的vote_weight,也就是用户实际给出的是1/2/3/4/5中的哪个分值。

现有代码参考

检查用户是否在指定维度投票的视图代码

<% if (user_signed_in?) && (current_user.voted_for? @stadium, :vote_scope => 'location') %>
<p>Current user has rated the location for this Stadium</p>    
<% else %>
<p>Current user has NOT rated the location for this Stadium</p>    
<% end %>

投票提交视图代码

<%= link_to like_stadium_path(@stadium, :score => 1, :vote_scope => 'location'), method: :put do %>
<button class="mt-4 w-full border-primary-500 border border-transparent rounded-md py-3 px-8 flex items-center justify-center text-base font-medium text-primary-500 hover:bg-primary-700 hover:text-white focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500">
Vote 1
</button>
<% end %>
<%= link_to like_stadium_path(@stadium, :score => 2, :vote_scope => 'location'), method: :put do %>
<button class="mt-4 w-full border-primary-500 border border-transparent rounded-md py-3 px-8 flex items-center justify-center text-base font-medium text-primary-500 hover:bg-primary-700 hover:text-white focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500">
Vote 2
</button>
<% end %>

<%= link_to like_stadium_path(@stadium, :score => 3, :vote_scope => 'location'), method: :put do %>
<button class="mt-4 w-full border-primary-500 border border-transparent rounded-md py-3 px-8 flex items-center justify-center text-base font-medium text-primary-500 hover:bg-primary-700 hover:text-white focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500">
Vote 3
</button>
<% end %>

<%= link_to like_stadium_path(@stadium, :score => 4, :vote_scope => 'location'), method: :put do %>
<button class="mt-4 w-full border-primary-500 border border-transparent rounded-md py-3 px-8 flex items-center justify-center text-base font-medium text-primary-500 hover:bg-primary-700 hover:text-white focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500">
Vote 4
</button>
<% end %>

<%= link_to like_stadium_path(@stadium, :score => 5, :vote_scope => 'location'), method: :put do %>
<button class="mt-4 w-full border-primary-500 border border-transparent rounded-md py-3 px-8 flex items-center justify-center text-base font-medium text-primary-500 hover:bg-primary-700 hover:text-white focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500">
Vote 5
</button>
<% end %>

stadiums_controller.rb 代码

def upvote 
  @stadium.upvote_by current_user, :vote_scope => params[:vote_scope], :vote_weight => params[:score]
  redirect_back(fallback_location: root_path)
end 

def downvote # 删除数据库中的投票记录
  @stadium.unliked_by current_user, :vote_scope => params[:vote_scope]
  redirect_back(fallback_location: root_path)
end

routes.rb 代码

resources :stadiums do
  member do
    put "like", to: "stadiums#upvote"
    put "unvote", to: "stadiums#downvote"
  end
end

解决方案

你可以直接通过votes_for关联查询指定条件的投票记录,直接取出vote_weight值,有两种常用写法:

  1. 从用户侧查询
# 直接获取当前用户在指定维度下对场馆的打分值,未投票返回nil
user_score = current_user.find_votes_for(votable: @stadium, vote_scope: 'location').first&.vote_weight
  1. 从资源侧查询
# 写法更简洁,直接返回对应分值,未投票返回nil
user_score = @stadium.votes_for.where(voter: current_user, vote_scope: 'location').pick(:vote_weight)

你可以把逻辑整合到原有的视图代码中,直接展示用户的打分:

<% if user_signed_in? %>
  <% user_score = @stadium.votes_for.where(voter: current_user, vote_scope: 'location').pick(:vote_weight) %>
  <% if user_score %>
    <p>你已为该场馆的位置打分:<%= user_score %> 分</p>    
  <% else %>
    <p>你还没有为该场馆的位置打分</p>    
  <% end %>
<% end %>

内容的提问来源于stack exchange,提问作者tommers

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 05:36:00