【问题标题】:How do I sum a many to many value?如何对多对多值求和?
【发布时间】:2012-05-14 04:28:42
【问题描述】:

每个用户可以有很多资源,每个资源都有很多投票,每个投票都有一个价值属性,我想将所有特定用户的资源相加。

如果我以语法错误的方式输入,我想要类似...

@user.resources.votes.sum(&:value),但这显然行不通。

我认为我需要使用collect,但我不确定?

这是我得到的最接近的,但它会打印出来,呵呵

<%= @user.resources.collect { |r| r.votes.sum(&:value) } %>

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-3 ruby-on-rails-3.1 collect


    【解决方案1】:

    我建议在 User 和 Vote 对象之间建立has_many :through 关系。像这样设置模型:

    class User < ActiveRecord::Base
      has_many :resources
      has_many :votes, :through => :resources
    end
    
    class Resource < ActiveRecord::Base
      belongs_to :user
      has_many :votes
    end
    
    class Vote < ActiveRecord::Base
      belongs_to :resource
    end
    

    完成此操作后,您只需调用 user.votes 并对该集合做任何您想做的事情。

    有关has_many :through 关系的更多信息,请参阅本指南:http://guides.rubyonrails.org/association_basics.html#the-has_many-through-association

    【讨论】:

    • 抱歉给您带来了困惑,我不确定您所说的是否仍然适用。我确实有关系,但我试图统计用户提交的所有资源的所有“全球”投票(其他人对该人资源的所有投票)。如果我做 User.votes 它只会计算那个人创建的选票
    【解决方案2】:

    您如何知道谁投票拥有 Vote 实例?您的投票模型必须具有 voter_id 字段和附加关联:

    # in Vote.rb
    belongs_to :voter, class_name: 'User', foreign_key: 'voter_id'
    

    在您的用户模型中:

    # in User.rb
    has_may :submited_votes, class_name: 'Vote', foreign_key: 'voter_id'
    

    所以,@user.votes(正如 David Underwood 提议的那样)会给你@user 资源的投票。 @user.submited_votes 会给你@user 提交的投票。

    仅使用用户

    【讨论】:

    • 对不起,我不明白你的意思。我想要做的基本上是 sum = 0; @user.resources.each 做 { |resource| sum += resource.votes.sum(&:value) }
    • 那段代码可以用,但是太长了,我只想写一行
    • 如果您有正确指定的关系,那么您将能够通过@user.votes.sum(:value) 计算总和。
    • 那不是只能找到@user的user_id的投票吗?
    • [无法编辑,必须重新创建。您的 cmets 太快了,所以在发布我的评论后,我意识到您已经发布了 2] 每个用户 ... has_many votes - 这从您的问题中不清楚!我建议做同样的事情!现在我看得更清楚了。看起来你需要:User.find(1).resources.joins(:votes).sum('votes.value').
    【解决方案3】:

    总而言之,这应该可行或非常接近。

    sum = 0
    @user.resources.each do |r|
    r.votes.each do |v|
        sum += v.value
    end
    end
    

    这可能对你有用:

    @user.resources.map {|r| r.votes.sum(:value)}.sum
    

    你有多少条记录,有一种方法可以将它推送到数据库级别,我相信,我必须检查一下,但如果只有几条记录,那么在 ruby​​ 中这样做可能没问题

    【讨论】:

    • 这可以工作,但我试图将它全部放在一条线上,理想情况下使用某种 Proc,只是为了保持我的这部分代码干净
    【解决方案4】:

    试试这个代码

    @user.resources.map(&:votes).flatten.map(&:value).sum
    

    【讨论】:

    • 有效,但在调用 SQL 时可能是灾难性的,不是吗?
    猜你喜欢
    • 2020-07-24
    • 2018-06-27
    • 2013-08-05
    • 1970-01-01
    • 2023-03-22
    • 2023-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多