2013-07-30 3 views
0

У меня есть дефект модели с атрибутом found_in. У меня есть hash test_phases, чьими ключами являются различные этапы тестирования, а значение - массив значений found_in. Есть ли способ сгруппировать Дефект с помощью test_phases? что-то вроде Defect.group_by (? test_phases) ?.Ruby Rails 3.2 Как group_by хешем массива атрибутов?

кода я использую некрасиво

defects = {} 
test_phases.each do |test_phase, found_ins| 
    defects[test_phase] ||= Defect.where(found_in: found_ins].all 
end 

ответ

1

Вам не нужно сгруппировать, так как вы итерацию хэша (без дубликатов ключей), выходной хэш не будет иметь несколько элементов с помощью ключа , Просто используйте map + Hash (или mash для Грани знатоков):

defects = Hash[test_phases.map do |test_phase, found_in_values| 
    [test_phase, Defect.where(found_in: found_in_values)] 
end] 
+0

Итерация по хэш может привести к п SQL запросов, где n - количество ключей в test_phases. Я надеялся, что есть способ сделать 1 sql-запрос, так же как Defect.select ('found_in', count (id) в качестве отставаний) .group ('found_in'). – user2371769

+0

Да, это вызовет N запросов. Не совсем уверен, что в чистом AR есть способ сделать это с помощью 1 запроса. – tokland

+0

Есть ли способ передать массив ключей в хэш? Например, будет ли это выполнимо: errors = Defect.select ('found_in', count (id) как backlogs.group ('found_in'). Test_phases.each do | test_phase, found_in_values ​​| test_phase_backlogs = errors [found_in_values]? – user2371769

0

Я решил эту проблему, создав модель TestPhase с соединительной таблице DefectFound

test_phase.rb: 
    has_many :defect_founds 

defect_found.rb: 
    belongs_to :test_phase 

defect.rb: 
    belongs_to :defect_found, foreign_key: :found_in, primary_key: :name # defect_found.name = defect.found_in 
    has_one :test_phase, through: :defect_found 

controller: 
    @defects = Defect.includes(:test_phase).select('found_in, COUNT(id) as backlog').group(:found_in).group_by(&:test_phase) 

view: 
    %table 
     - @defects.each do |test_phase, backlogs| 
     %tr 
      %td= test_phase.name if test_phase.present? 
      %td= backlogs.map(&:backlog).inject(:+) 

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

  • Нет связанных вопросов^_^