2011-07-13 3 views
8

Ben böyle bir sorgu: 500 ya da öylesine kayıtların dizisi döndürürtutmamışsanız

locations = Location.order('id ASC').limit(10) 

- tüm kayıtlar içinde Tablo - yani limit cümlesi göz ardı ediliyor.

Yine de ucunda bir .ALL koyarsanız: çalıştığını ve 10 kayıtları döndürür

locations = Location.order('id ASC').limit(10).all 

.

Bu kod bir komisyon görevinde çalıştırılıyor ve PostgreSQL kullanıyorum eğer bu bir fark yaratıyorsa.

Neden böyle yapıyor? Elbette .all gerekli olmamalıdır. Neyi kaçırıyorum?

+0

ile üçüncü satırda SQL sorgusu yapar: ... sorgular .first, .all sürece tetiklenmezler Raylar hangi sürümünü – apneadiving

+0

eklenir kullanıyor musun? Çünkü 3.0.9 kullanıyorum ve bunu üretemiyorum. – Gerry

+0

Rails hangi versiyonunu kullanıyorsunuz? Rails 3.0x'te benim için çalışıyor. Hangi sorguyu çalıştırdığını görmek için sonuna ".to_sql" eklemeyi denediniz mi? id ASC LIMIT 10 TARAFINDAN "yerler" SİPARİŞ * SEÇ "yerler" ama ikincisi .all çünkü başarısız. İlk örneğe to_sql ekleme – samullen

cevap

5

Davranış, ayarlandıktan sonra locations değişkenini nasıl kullandığınıza bağlı olduğunu düşünüyorum. Bunun nedeni, Location.order('id ASC').limit(10) kayıtlarını sorgulamaması, ancak ActiveRecord::Relation türünde bir nesneyi döndürmesidir. Sorgu, yalnızca bu nesne üzerinde all, first, each, map vb. Benim test

,

Location.order('id ASC').limit(10).map { |l| l.id } 

beklediğiniz gibi 10 kimlikleri dizisi döndürür. konum satırların tam sayısını (sınır döndü satırı sayısı değil döndüren SQL

SELECT COUNT(*) FROM "locations" LIMIT 10 

yürütür çünkü

Location.order('id ASC').limit(10).count 

, veritabanındaki konumların toplam sayısını döndürür sayımın kendisi).

Location.order('id ASC').limit(10) sonucunu bir dizi olarak işleme tabi tutuyorsanız, all eklediyseniz, aynı sonucu elde etmelisiniz. count'u arıyorsan, yapmazsın. Ne yazık ki, bence onlar da aynı şekilde davranmalı ve bir dizi yerine bir ActiveRecord::Relation ile uğraştığınızı bilmemelisiniz. Burada Tamam

+0

bir dizinin içine girer, bu yüzden çivilenmiş olduğunu düşünüyorum. görünümüne "# {locations.size} öğe koyarken konumların boyutunu kontrol ediyordum, konumların bu noktada bir İlişki olmadığını unutmayın. Yani .size bir İlişki üzerinde farklı bir davranışa sahip gibi görünüyor ve bu Bağıntı üzerinde bir sorgu tarafından üretilen dizi kesinlikle yararlı değil. –

1

benim açıklama size Location.order('id ASC').limit(10).class yaptığım eğer Öncelikle ActiveRecord::FinderMethods içerir ancak bir yöntem all yok sonraki site with rails APIActiveRecord::Relation üzerinde ActiveRecord::Relation görürsünüz ve orada bakarsanız sonraki

bulacaksınız olduğunu
# File activerecord/lib/active_record/relation/finder_methods.rb, line 142 
def all(*args) 
    args.any? ? apply_finder_options(args.first).to_a : to_a 
end 

böylece zamanda railscasts sözü edilen to_a yöntem bu yöntem

def to_a 
    ... 
    @records = eager_loading? ? find_with_associations : @klass.find_by_sql(arel.to_sql) 
    ... 
    @records 
end 
olarak tanımlanır aramaları

yüzden ben tembel yükleme bağlantısı verilen olup olmadığını merak @records = eager_loading? ? find_with_associations : @klass.find_by_sql(arel.to_sql)