我正在编写一份问卷供用户填写。用户可以多次回答每个问题。回复有一个问题键,可以将它们与问题配对。我想获取用户当前响应的完整集合而不检索用户创建的每个响应。
响应表如下所示:
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
答案 0 :(得分: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
答案 1 :(得分: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)