2013-11-02 6 views
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-запрос, который делает то, что я хочу, заказывая строки перед тем, как делать ГРУППА ПО. Есть ли разумный способ использовать это в Response :: current?

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

ответ

0

Это решение основано на идентификаторах быть последовательным:

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) 
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 
+0

Я пробовал это, и он 'group by' перед' order by' - возвращает самый старый ответ для каждого вопроса. Используя ваш код, это результат SQL: ответы «SELECT». * FROM 'ответы' WHERE 'response'. 'User_id' = 1011645 GROUP BY question_key ORDER BY created_at DESC' – yerdua

Смежные вопросы