我有以下型号的
class Project
has_many :contributions
end
class Contributor
has_many :contributions
end
class Contribution
belongs_to :contributor
belongs_to :project
end
我试图找出在多少项目中有多少贡献者,并按贡献的项目数量排序。
示例:
- Person 1 made contribution to Project 1
- Person 1 made contribution to Project 2
- Person 2 made contribution to Project 1
- Person 2 made contribution to Project 3
- Person 2 made contribution to Project 4
- Person 3 made contribution to Project 4
- Person 3 made contribution to Project 5
在这种情况下,
- Person 1 made 2 contributions in 2 seperate projects.
- Person 2 made 3 contributions in 3 seperate projects.
- Person 3 made 2 contributions in 2 seperate projects.
这意味着
- 2 people made 2 contributions
- 1 person made 3 contributions
结果为:{ 2 => 2, 1 => 3 }
以下是我所做的:
Contributor.joins(:contributions).order("count(contributions.id) asc").group("contributor.id").count
这给了我每个贡献者的贡献数量,但不是我想要的。
试试这个:
Contributor.joins(:contributions).order("count(contributions.id) asc").group("contributor.id").count.group_by{|i| i.last}.map{|a| [a.last.count,a.first]}
# First, you need to count the distinct contributions for every contributor
contributors_info = Contributor.joins(:contributions).group("contributors.id").count("DISTINCT contributions.id")
(0.4ms) SELECT COUNT(DISTINCT contributions.id) AS count_distinct_contributions_id, contributors.id AS contributors_id FROM "contributors" INNER JOIN "contributions" ON "contributions"."contributor_id" = "contributors"."id" GROUP BY contributors.id
=> {1=>2, 2=>3, 3=>2}
你希望你的结果是这样的:
- 2人做出2项贡献
- 1人做出3项贡献
- 结果是:{2=>2,1=>3}
但如果有另外一个人做出了4个贡献,你的结果会是:{ 2 => 2, 1 => 3, 1 => 4 }
,这不是一个有效的散列。这意味着您必须更改结果结构,我建议您使用contribution_count
作为键,人员计数作为值,因为contribution_count
将是唯一的。
# Then, use the previous information to get how many people made how many contributions
contributors_info.reduce({}) do |result, (_, contribution_count)|
result[contribution_count] = (result[contribution_count] ||= 0) + 1
result
end
# two contributions => 2 people, three contributions => 1 person
=> {2=>2, 3=>1}