2013-03-21 3 views
8

find_in_batches과 같은 것을 사용하고 싶지만 완전히 인스턴스화 된 AR 개체를 그룹화하는 대신 ID와 같은 특정 속성을 그룹화하고 싶습니다. 그래서, 기본적으로, find_in_batchespluck 사용의 혼합물 :레일 : AREL을 사용한 일괄 속성 쿼리

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

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

자신 또는 페이지를 매기는 것 같은 보석을 매김에 반복 또는 오프셋/LIMIT 논리를 작성하지 않고도 (어쩌면 Arel와 함께)이 할 수있는 방법이 있나요 카미나리?

답변

2

이 여기에 이상적인 솔루션이 아니라 그냥 복사 - 붙여 넣기하는 방법 find_in_batches 대부분이다하지만 (검증되지 않은) 레코드의 배열 대신의 관계를 얻을 수 - 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 
이와

, 당신은 할 수 있어야한다 :

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

이 (기록을 인스턴스화 계산을, primary_key_offset 특히 관련하여) 최상의 구현되지 않습니다,하지만 당신은 정신을 얻는다.

+0

정말 좋은 시도였습니다. 하지만 나는 여러 프로젝트에서 배포 할 수있는 라이브러리에 상기 논리를 적용하기를 원하기 때문에 비 원숭이 패치 솔루션을 선호합니다. AR에서 코드 삽입과 관련하여 최대한 적게 관입하고 싶습니다. . – ChuckE

+0

좋은 지적 ... 그래서 그것을 클래스 메소드로 만드십시오. 나는 당신의 라이브러리가 어쨌든 모델에 포함될 것이며, AR이 사용되는 한 똑같이 작동해야한다고 생각합니다. –

+0

.limit 및 .offset ARel 메서드를 사용하여 종료되었습니다. 나는 레일즈 용으로 즉시 사용 가능한 솔루션을 갖는 것이 좋을 것이라고 말하고 있습니다. – ChuckE