1

我正在为用户填写一份调查问卷。用户可以多次回答每个问题。响应有一个 question_key 将它们与他们的问题配对。我想在不检索用户创建的每个响应的情况下获取用户当前响应的完整集。

响应表如下所示:

create_table "responses", :force => true do |t|
  t.string   "question_key", :null => false
  t.text     "value",        :null => false
  t.integer  "user_id",      :null => false
  t.datetime "created_at"
  t.datetime "updated_at"
end

这是响应类的相关部分:

class Response < ActiveRecord::Base
  def self.current
    recent.uniq {|response| response.question_key}
  end

  scope :recent, order('created_at DESC')
end

user.responses.current得到一组响应,但它似乎真的效率低下。它获取用户曾经创建的所有响应,然后为每个唯一值丢弃除最新响应之外的所有响应question_key

我确实想出了一个 SQL 查询,它可以满足我的需求,在进行 GROUP BY 之前对行进行排序。是否有合理的方法在 Response::current 中使用它?

SELECT *
FROM (
    SELECT *
    FROM responses
    WHERE user.id = 6
    ORDER BY created_at DESC ) as user_responses
GROUP BY question_key
4

2 回答 2

0

您可以使用该group方法在活动记录中执行分组依据。

Responses.where(user_id: '123').order('created_at DESC').group('question_key')

所以你的代码会是这样的:

class Response < ActiveRecord::Base
  scope :recent, order('created_at DESC')
  def self.current
    recent.group('question_key')
  end
end
于 2013-11-02T00:46:58.290 回答
0

此解决方案依赖于连续的 id:

class Response < ActiveRecord::Base
  def self.current
    where(id: group(:question_key).maximum(:id).values)
  end
end

当获取用户的当前响应时,它会导致两个查询 ( user.responses.current),但它会避免返回所有用户的响应。

SELECT MAX(`responses`.`id`) AS maximum_id, question_key AS question_key FROM `responses` WHERE `responses`.`user_id` = 6 GROUP BY question_key
SELECT `responses`.* FROM `responses` WHERE `responses`.`user_id` = 6 AND `responses`.`id` IN (452, 447, 9, 225, 190, 230, 240)
于 2013-12-02T19:18:08.737 回答