1

我的模型是:

class Link < ActiveRecord::Base
    has_many :votes
    belongs_to :user
end

class Vote < ActiveRecord::Base
    belongs_to :user
    belongs_to :link
end

class User < ActiveRecord::Base

    has_secure_password

    has_many :links
    has_many :votes
end

我有一个页面,其中列出了系统中的所有链接。对于每个链接,我想显示所有投票的当前总和,以及提出请求的用户是否对该特定链接进行了投票(如果是,那么该投票的价值是多少)。我想以最有效的方式做到这一点。

目前为了返回链接和投票总和,我在我的链接控制器中有这个:

def index
    @links = Link.all(:joins => :votes, :select => "links.*, sum(votes.value) as votes_total", :group => "links.id")
end

效果很好,只需一个电话就可以为我提供所有信息。所以我的问题是,我是否需要进行第二次查询以返回 current_user 的投票(如果存在),或者我可以以某种方式将其合并到我的第一个查询中?

此外,也许我应该在数据库中设置某种 sum_caching 但我也不确定最好的方法。有什么想法吗?

4

1 回答 1

0

你可以这样做:

@links = Link.
  joins(:votes). 
  select(
    "links.*, sum(votes.value) as votes_total, sum(case votes.user_id when #{current_user.id} then votes.value else 0 end) as current_vote", 
    :group => "links.id"
  )

这将为您提供当前用户的投票值为@links.first.current_vote. 当然,如果您的系统的投票值为 0,它不会区分“当前用户在此链接上投票 0”和“当前用户未在此链接上投票”。我想,您可以添加另一个选定的值 ( sum(case votes.user_id when #{current_user.id} then 1 else 0 end) as current_vote_exists) 来处理它。

自然,在像这样插入 SQL 和/或查找 ActiveRecord 附带的 SQL 清理工具时,您需要非常小心。

于 2013-10-16T01:34:11.253 回答