2013-03-21 14 views
8

Chciałbym użyć czegoś takiego jak find_in_batches, ale zamiast grupowania w pełni instancji obiektów AR, chciałbym zgrupować pewien atrybut, na przykład, powiedzmy, id. Tak więc, w zasadzie, mieszanka użyciu find_in_batches i pluck:Szyny: zapytania grupowania atrybutów przy użyciu AREL

Cars.where(:engine => "Turbo").pluck(:id).find_in_batches do |ids| 
    puts ids 
end 

# [1, 2, 3....] 
# ... 

Czy istnieje sposób, aby to zrobić (może z AREL) bez konieczności pisania OFFSET logiki/ograniczę się lub powracającym do paginacji perełki jak zostanie podzielony na strony lub kaminari?

Odpowiedz

2

nie jest idealnym rozwiązaniem, ale tutaj jest sposób, że tylko kopia pasty większość find_in_batches ale daje związek zamiast szereg płyt (nieprzebadanych) - tylko małpy plaster go do Relation:

def in_batches(options = {}) 
    relation = self 

    unless arel.orders.blank? && arel.taken.blank? 
    ActiveRecord::Base.logger.warn("Scoped order and limit are ignored, it's forced to be batch order and batch size") 
    end 

    if (finder_options = options.except(:start, :batch_size)).present? 
    raise "You can't specify an order, it's forced to be #{batch_order}" if options[:order].present? 
    raise "You can't specify a limit, it's forced to be the batch_size" if options[:limit].present? 

    relation = apply_finder_options(finder_options) 
    end 

    start = options.delete(:start) 
    batch_size = options.delete(:batch_size) || 1000 

    relation = relation.reorder(batch_order).limit(batch_size) 
    relation = start ? relation.where(table[primary_key].gteq(start)) : relation 

    while (size = relation.size) > 0  

    yield relation 

    break if size < batch_size 

    primary_key_offset = relation.last.id 
    if primary_key_offset 
     relation = relation.where(table[primary_key].gt(primary_key_offset)) 
    else 
     raise "Primary key not included in the custom select clause" 
    end 
    end 
end 

z tym, powinieneś być w stanie to zrobić:

Cars.where(:engine => "Turbo").in_batches do |relation| 
    relation.pluck(:id) 
end 

nie jest to najlepsza możliwa realizacja (szczególnie w odniesieniu do primary_key_offset obliczenia, które tworzy wystąpienie rekordu), ale masz ducha.

+0

to była naprawdę dobra próba. Wolę jednak rozwiązanie, które nie jest małpopodobne, ponieważ chcę zastosować tę logikę w bibliotece, która może być dystrybuowana przez kilka projektów, i chciałbym być mniej inwazyjny, jeśli to możliwe, w odniesieniu do iniekcji kodu w AR . – ChuckE

+0

Dobra uwaga ... więc spraw, by była to metoda klasowa. Domyślam się, że twoja biblioteka będzie mimo wszystko uwzględniona w modelach i powinna działać tak samo długo, jak długo używa AR. –

+0

Zakończono używając metod .limit i .offset ARel. Mówię tylko, byłoby miło mieć takie gotowe rozwiązanie dla Rails. – ChuckE

Powiązane problemy