问题
I have these models
- Issue
- Vote
Issue has_many votes and Vote belongs_to issue. The Vote model has a boolean vote attribute. On the issues index view I want to cycle through the issues and display the title, body, an up vote button, a down vote button, and respective labels that show how many up votes and down votes there currently is. I do this with a form with hidden fields for issue_id and vote (1 or 0). Methods on the Issue model are supposed to count the votes. But I keep getting 0 returned. Totalvotes_count works but the other two don't. In the server log I see the votes being created with the proper issue_id and vote value but the queries aren't working for some reason.
Issue model
class Issue < ActiveRecord::Base
attr_accessible :body, :end_at, :title
validates_presence_of :title, :body, :end_at
has_many :votes
def upvotes_count
votes.count(:conditions => "vote = 1")
end
def downvotes_count
votes.count(:conditions => "vote = 0")
end
def totalvotes_count
votes.count
end
end
index.html.erb
<% @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 issue.upvotes_count.to_s + " 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 issue.downvotes_count.to_s + " Down", :class => 'down-vote' %>
<% end %>
</div>
</li>
<% end %>
Votes Controller
class VotesController < ApplicationController
def index
@votes = Vote.find(:all, :include => :issue)
end
def new
@vote = Vote.new(params[:vote])
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => @vote }
end
end
def create
@vote = Vote.new(params[:vote])
respond_to do |format|
if @vote.save
format.js
format.html { redirect_to issues_path }
else
format.html { redirect_to issues_path }
end
end
end
end
Issues controller (partial)
class IssuesController < ApplicationController
# GET /issues
# GET /issues.json
def index
@issues = Issue.all
@vote = Vote.new
respond_to do |format|
format.html # index.html.erb
format.json { render json: @issues }
end
end
回答1:
I believe your problem is that you do not have "self
" called on your methods in the model, but as tamersalama mentioned this is likely overkill for simple vote tracking. It is probably just easiest to write a simple +1 method on an :upvote
and :downvote
attribute.
回答2:
What is the default value of vote
. If it's NULL - then neither would work.
Reading the question more carefully - it looks like the value in vote
determine if it's an up or downvote. I suggest you'd use a STI (single-table inheritance) mechanism for Vote
, where you'd create a type column to store the type of vote (either :upvote, :downvote), with an index on the type attribute.
All of this however seems like an overkill (depending on the rest of your domain). You could simply cache votes along with each of the issues. A column for upvote and one for downvote would suffice. Unless you'd want to track other attributes on Vote (like people who upvotes for example).
来源:https://stackoverflow.com/questions/12680437/ror-voting-system-counting-votes-by-condition-vote-true-or-vote-false-not-w