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。这是我在控制台中看到的:' 1.9.3p194 :005 > @issue.votes.count(:conditions => "vote = 1") (0.3ms) 从 "votes" WHERE "votes" 中选择 COUNT(*)。 "issue_id" = 5 AND (vote = 1) => 0' 生成的查询是正确的。您确定您确实将该 Vote 对象保存到了数据库中吗? 不,我认为这可能是我的问题。在我的 IssuesController 索引操作中,我有 @vote = Vote.new(params[:vote])。应该改为创建吗?【参考方案2】:

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】:

您真的需要自己存储选票吗?如果您没有任何其他约束,则可以使用两个字段:upvotesdownvotes。然后你定义两个动作,“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 投票系统。如何计算票数、反对票和总票数?的主要内容,如果未能解决你的问题,请参考以下文章

基于php004网络投票在线投票系统

c语言编程:设计一个投票程序,每输入一个候选人名字,其票数自增一。最后输出各自得票结果

贪心练习

用java编写一个统计投票结果程序

DBA投票项目回顾——定位蓝海的LOTS

如何从数据库中实时更新上票和下票数而不需要重定向?