Rails:通过连接表获取关联计数

问题描述 投票:0回答:3

我有一个名为“Fact”的实体,这个实体与另一个名为“User”的实体有关系,这种关系被称为“反馈”,每当一个人给出他得到的反馈时,它有3个字段[user_id,fact_id,score]反馈(user_id)到什么事实(fact_id)和什么是合格的(0,1,2)。那么,现在我想得到他们的资格计算的事实清单,例如:

fact : {id: 3, name: "some name", number_of_zero: 7, number_of_one: 3, number_of_two: 3}

其中number_of是合格的次数。

数据库架构:

  create_table "facts", force: :cascade do |t|
    t.string "title"
    t.string "description"
    t.integer "user_id"
  end

  create_table "users", force: :cascade do |t|
    t.string "name"
    t.string "last_name"
  end

create_table "feedbacks", force: :cascade do |t|
    t.integer "score"
    t.integer "user_id"
    t.integer "fact_id"
    t.index ["fact_id"], name: "index_feedbacks_on_fact_id"
    t.index ["user_id"], name: "index_feedbacks_on_user_id"
  end

关系:

class Feedback < ApplicationRecord
  belongs_to :user
  belongs_to :fact
end
ruby-on-rails ruby postgresql activerecord ruby-on-rails-5
3个回答
1
投票
Fact.
  group(:id, :name).
  select(:id, name).
  left_joins(:feedbacks).
  select("COUNT(feedbacks.id) FILTER (WHERE score = 0) AS number_of_zero").
  select("COUNT(feedbacks.id) FILTER (WHERE score = 1) AS number_of_one").
  select("COUNT(feedbacks.id) FILTER (WHERE score = 2) AS number_of_two")

你需要left_joins,以便返回0反馈的事实(每个计数列为0)。

正如Rohan所说,你需要在has_many :feedbacks中添加fact.rb

有更复杂的解决方案可以适应任何数量的可能分数,但在这种情况下,这将是过分热心的。

编辑:对于SQLite(我认为它支持相关的子查询...)

Fact.
  select(:id, name).
  select("(SELECT COUNT(*) FROM feedbacks WHERE score = 0 AND fact_id = facts.id) AS number_of_zero").
  select("(SELECT COUNT(*) FROM feedbacks WHERE score = 1 AND fact_id = facts.id) AS number_of_one").
  select("(SELECT COUNT(*) FROM feedbacks WHERE score = 2 AND fact_id = facts.id) AS number_of_two")

0
投票

根据帖子中提供的描述,您似乎想要事实细节以及每个uniq事实的得分。

下面提到的东西可以帮助您实现:

Fact.joins(:feedbacks).select("facts.id, facts.title,CASE when feedbacks.score is 0 
then count(feedbacks.score) as score_0 end,
CASE when feedbacks.score is 1 then count(feedbacks.score) as score_1 end,
CASE when feedbacks.score is 2 then count(feedbacks.score) as score_2 end")
.group("feedbacks.score")

以上查询是将反馈与事实相结合,然后对得分值进行分组,因为只有三个值,即0,1,2(如帖子中所述)。


0
投票
Model:
class Feedback < ApplicationRecord
  belongs_to :user
  belongs_to :fact
end
class Fact < ApplicationRecord
 has_many :feedbacks
end
 fact = Fact.all
  array = []
 fact.each do |each_fact|
    arr = {}
    each_fact.feedbacks do |each_feedback|
       arr["id"] = each_feed_back.id
       arr["name"] = each_feedback.name
       arr["no_of_zero"] = each_feedback.score 
       array << arr
   end
end
© www.soinside.com 2019 - 2024. All rights reserved.