2012-12-04 25 views
1

我有一个PostReplyVote模型(多晶型):使用“.order(params [])”与实例方法?

create_table "posts", :force => true do |t| 
    t.text  "content",  :limit => 255 
    t.integer "user_id" 
    t.datetime "created_at",         :null => false 
    t.datetime "updated_at",         :null => false 
    t.string "title" 
    t.integer "replies_count",    :default => 0, :null => false 
    t.integer "category_id" 
    end 

    create_table "replies", :force => true do |t| 
    t.text  "content" 
    t.integer "post_id" 
    t.integer "user_id" 
    t.datetime "created_at", :null => false 
    t.datetime "updated_at", :null => false 
    end 

    create_table "votes", :force => true do |t| 
    t.integer "votable_id" 
    t.string "votable_type" 
    t.integer "user_id" 
    t.integer "polarity" 
    t.datetime "created_at", :null => false 
    t.datetime "updated_at", :null => false 
    end 

我需要职位的total_votes和回复所以我创建一个实例方法:

post.rb和reply.rb :

def total_votes 
    self.votes.map {|v| v.polarity }.sum 
    end 

所以我可以用它来帖和回复排序:

主页:

default_order = "created_at DESC" 
params[:order_by] ||= default_order 
@feed_items = @post.replies.paginate(page: params[:page], 
             per_page: 10).order(params[:order_by]) 

所以现在,我不是很确定什么视图order_by后添加:

<span><%= link_to 'total_votes DESC', root_path(order_by: HERE) %></span> 

我试图&:total_votes DESCtotal_votes DESC,但没有奏效。

这样做的正确方法是什么? (我认为这是一个有点不必要的total_votes列添加到两个postsreplies表,但不知道这是获得更好的性能?)

回答

2

我会使用数据库做加法的开始,但这有点棘手,因为您需要按计算出的值进行排序(“聚合”),但我们先将其置于一边。

当您在控制器中设置实例变量时,您的视图将按照确定的顺序显示项目。因此,在控制器,你可以检测到有一个order_by参数(例如/feed?order_by=total_votes,并相应地加载@feed_items,如

def index 
    if params[:order_by] && params[:order_by] == 'total_votes' 
    sort_order = "total_votes DESC" 
    else 
    sort_order = "created_at DESC" 
    end 
    @feed_items = @post.replies.paginate(page: params[:page], 
            per_page: 10).order(sort_order) 
end 

然后在您看来,变化排序顺序,创建一个link_to,增加了查询字符串参数(见the link_to api doc最后一个例子,例如

<%= link_to "Sort by Total Votes", root_path(:order_by => 'total_votes') %><br /> 
<%= link_to "Sort by Time", root_path %><br /> 

你的另一个问题是如何做的票数排序。这个答案可以提供一个良好的开端,并回答您的性能问题1 on:Rails: Order by sum of two columns

+0

因此,在实现代码之前,我必须将'total_votes'列添加到posts表和另一个'total_votes'列到答复表中?我知道':order_by =>'total_votes''与db中的现有表一起工作。我只是不知道如何用实例方法做到这一点。 – alexchenco

+0

我刚编辑答案。我认为“不”,你应该使用'sum'来即时计算总和。这可能是您可以从模型中调用的Votes模型的范围(传递所需信息),然后替换'.order()'谓词的好例子。 –

+0

我明白了,你能给我一个范例在Votes模型上的例子吗? – alexchenco