RoR 投票系统。如何计算票数、反对票和总票数?
Posted
技术标签:
【中文标题】RoR 投票系统。如何计算票数、反对票和总票数?【英文标题】:RoR voting system. How to count up votes, down votes, and total votes? 【发布时间】:2012-09-30 23:18:25 【问题描述】:我正在尝试创建一个投票系统。正在投票的模型是问题,我有另一个名为 Vote 的模型,它拥有 issue_id 和 0 或 1 的投票值。投票是使用带有隐藏字段的表单创建的。这是问题索引视图。
<h1>Votes</h1>
<% @issues.each do |issue| %>
<li>
<div class="issue">
<h2><%= issue.title %></h2>
<p><%= issue.body %></p>
<%= form_for(@vote, :remote => true) do |f| %>
<%= f.hidden_field "issue_id", :value => issue.id %>
<%= f.hidden_field "vote", :value => 1 %>
<%= submit_tag "Up", :class => 'up-vote' %>
<% end %>
<%= form_for(@vote, :remote => true) do |f| %>
<%= f.hidden_field "issue_id", :value => issue.id %>
<%= f.hidden_field "vote", :value => 0 %>
<%= submit_tag "Down", :class => 'down-vote' %>
<% end %>
</div>
</li>
<% end %>
问题和投票之间存在has_many 和belongs_to 关系。我想在每个问题的按钮旁边显示赞成票和反对票的数量。所以我需要为每个问题拉出所有投票 = 1 的选票,以及所有投票 = 0 的选票,并计算每个问题。也想知道总票数。我该怎么做?我在问题模式中的投票模型问题关联和 votes_count 列上设置了 counter_cache。这项工作应该在控制器还是模型中完成?
【问题讨论】:
我不认为我将要链接的内容与您尝试构建的内容相同......但它可能会有所帮助,也许?这是链接:railscasts.com/episodes/364-active-record-reputation-system ...当我阅读他们的网站时遇到了它。对整个 ruby/rails 来说有点新。无论如何,希望它有所帮助。 【参考方案1】:我自己没有尝试过,但您应该尝试向您的Issue
模型添加一些方法,如下所示:
def upvote_count
votes.count(:conditions => "value = 1")
end
def downvote_count
votes.count(:conditions => "value = 0")
end
我在 Rails 文档中了解到这一点。您可以在这里亲自查看:
http://ar.rubyonrails.org/classes/ActiveRecord/Calculations/ClassMethods.html http://apidock.com/rails/ActiveRecord/Associations/CollectionAssociation/count
【讨论】:
我试过这个,但是当我尝试在视图中使用它们时,我不断收到未定义的方法错误。 如果没有确切的错误消息并且知道它发生在哪一行,我无法为您提供帮助。您是否将方法放在问题类中? 解决了我的问题。我使用的是@issue.upvote_count 而不是 issue.upvote_count。我还有另一个问题。当我使用 votes.count(:conditions => "vote = 1") 时,这些函数一直返回 0。这是我在控制台中看到的:'ActiveRecord 有一个 count
方法可以做你想做的事:http://api.rubyonrails.org/classes/ActiveRecord/Calculations.html#method-i-count
例如,在您的控制器中:
@upvotes_count = Vote.count(:conditions => "issue_id = #@issue.id AND value = 1")
@downvotes_count = Vote.count(:conditions => "issue_id = #@issue.id AND value = 0")
@allvotes_count = Vote.count(:conditions => "issue_id = #@issue.id")
【讨论】:
我正在尝试避免从数据库中获取记录,您建议的替代方案是什么? 这不会从数据库中获取记录。它会完全按照您的方式进行 SQL 计数。唯一的区别是代码会更短。【参考方案3】:您真的需要自己存储选票吗?如果您没有任何其他约束,则可以使用两个字段:upvotes
和 downvotes
。然后你定义两个动作,“upvote”和“downvote”,它们将相应的字段更新1。你可以原子地做,使用类似
(型号)
class Issue < AR::Base
def self.upvote(id)
self.where(:id => id).update_all("upvotes = upvotes + 1")
end
def self.downvote(id)
self.where(:id => id).update_all("downvotes = downvotes + 1")
end
end
(控制器)
class IssuesController < ApplicationController
def upvote
Issue.upvote(params[:id])
end
def downvote
Issue.upvote(params[:id])
end
end
(路由器)
resources :issues do
member do
post :upvote
post :downvote
end
end
(视图-haml)
= form_tag upvote_issue_path(@issue) do
= submit_tag "Up"
= form_tag downvote_issue_path(@issue) do
= submit_tag "Down"
【讨论】:
感谢您。我学到了很多。我想添加用户拥有投票权并按用户提取投票记录的功能,但是我认为我需要单独的模型。以上是关于RoR 投票系统。如何计算票数、反对票和总票数?的主要内容,如果未能解决你的问题,请参考以下文章