我使用Ruby on Rails创建了一个简单的博客应用程序,这两者都是我的新手。我想在我的/views/posts/index.html.erb视图中显示我最“投票”的帖子。以下是基础知识。
我创建了一个投票表,并成功允许用户对/views/posts/show.html.erb页面上的帖子进行“投票”。 VotesController将post_id传递给Votes表列post_id,并通过ajax将该帖子的投票计数返回到同一个显示页面。
class Vote
belongs_to :post`
end
和
class Post
has_many :votes
end
我想在/views/posts/index.html.erb中显示帖子标题及其投票次数,以具有最高投票数的帖子排序。
修改 使用下面的代码,我可以在Votes表中显示(在/views/posts/show.html.erb页面中)post_id,并为该post_id显示vote_count。即'55(7)'。想知道我是否也可以将post_title传递给投票表(到列post_title),然后只显示而不是post_id。这是完成该任务的代码。
class PostsController < ApplicationController
def index
@tag_counts = Tag.count(:group => :tag_name,
:order => 'count_all DESC', :limit => 20)
@vote_counts = Vote.count(:group => :post_id, :limit => 5)
conditions, joins = {}, nil
unless(params[:tag_name] || "").empty?
conditions = ["tags.tag_name = ? ", params[:tag_name]]
joins = :tags
end
@posts=Post.all(:joins => joins, :conditions=> conditions, :order => 'created_at DESC').paginate :page => params[:page], :per_page => 5
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => @posts }
format.json { render :json => @posts }
format.atom
end
end
VotesController
class VotesController < ApplicationController
def create
@post = Post.find(params[:post_id])
@vote = @post.votes.create!(params[:vote])
respond_to do |format|
format.html { redirect_to @post}
format.js
end
end
end
/views/posts/index.html.erb
Most Liked Posts<hr/>
<% @vote_counts.each do |post_id, vote_count| %>
<div id="tag-wrapper">
<%= link_to(post_id, posts_path(:post_id => post_id)) %>
(<%=vote_count%>)</div>
<% end %>
答案 0 :(得分:7)
您可以使用vote_fu插件(使用kandadaboggu-vote_fu版本)
class User
acts_as_voter
end
将vote_total
列(整数)添加到posts
表。
class Post
acts_as_voteable :vote_counter => true
end
现在您可以执行以下操作:
user.vote_for(post) # vote up
user.vote_against(post) # vote down
post.vote_total # sum of +ve and -ve votes
post.vote_count # count of votes
如果您使用vote_counter
指令,则会在posts
表中维护投票总额。无需额外的SQL来计算vote_total
。
要按vote_total对帖子进行排序,请执行以下操作:
Posts.all(:order => "vote_total DESC")
<强>披露强>
我维持kandadaboggu-vote_fu
宝石。
修改强>
要在当前架构中实现此功能,您可以执行以下操作:
Post.all(:joins => :votes, :select => "posts.*, count(*) as vote_total",
:group => "votes.post_id", :order => "vote_total DESC", :limit => 10)
修改2
您可以使用以下代码实现此功能以使用当前逻辑。 请注意,Rails使用INNER联接,因此如果没有投票,则不会选择帖子。您可以通过在创建帖子时投票一次来规避这一点。
我已修复您的paginate
电话。目前的逻辑非常低效。分页应用于从DB返回的数组,因此在执行分页之前会加载整个结果集。作为规则,请使用两个额外参数来处理paginate
类all
方法。
请注意,下面的SQL会给您的系统资源带来压力。您可能需要通过在vote_total
表格中存储posts
进行优化。
conditions, joins = {}, :votes
unless(params[:tag_name] || "").empty?
conditions = ["tags.tag_name = ? ", params[:tag_name]]
joins = [:tags, :votes]
end
@posts=Post.paginate(
:select => "posts.*, count(*) as vote_total",
:joins => joins,
:conditions=> conditions,
:group => "votes.post_id",
:order => "vote_total DESC",
:page => params[:page], :per_page => 5)
编辑3
创建帖子时的投票逻辑。
class Vote
belongs_to :user
belongs_to :post
end
class Post
belongs_to :user
after_create :self_vote
def self_vote
# I am assuming you have a user_id field in `posts` and `votes` table.
self.votes.create(:user => self.user)
end
end
帖子的迭代代码:
<% @posts.each do |post| %>
<p><%= link_to(post.title, post_path(post)) %></p>
<p>
Created <%= time_ago_in_words(post.created_at) %>.
Votes <%= post.vote_total %>
</p>
<% end %>
答案 1 :(得分:-1)
使用mysql查询。如下所示
@posts=Post.find_by_sql("select p.post, count(v.vote) as vote from posts p, votes v where v.post_id=p.id group by p.id order by vote DESC")
on rhtml
for post in @posts
post.post
post.vote
end