Modelimde varsayılan bir sıralama düzeni belirtmek istiyorum.
Böylece ben bir .where()
belirtmeden yapmak .order()
varsayılan sıralama kullanır. Ama bir belirtirsem .order()
, varsayılanı geçersiz kılar.
Modelimde varsayılan bir sıralama düzeni belirtmek istiyorum.
Böylece ben bir .where()
belirtmeden yapmak .order()
varsayılan sıralama kullanır. Ama bir belirtirsem .order()
, varsayılanı geçersiz kılar.
Yanıtlar:
default_scope
Bu, Rails 4+ için çalışır:
class Book < ActiveRecord::Base
default_scope { order(created_at: :desc) }
end
Rails 2.3, 3 için bunun yerine aşağıdakilere ihtiyacınız vardır:
default_scope order('created_at DESC')
Raylar 2.x için:
default_scope :order => 'created_at DESC'
created_at
Varsayılan sıralamanın yapılmasını istediğiniz alan nerede .
Not: ASC Artan için kullanılan koddur ve DESC azalan içindir ( desc
, DEĞİL dsc
!).
scope
Buna alıştıktan sonra şunları da kullanabilirsiniz scope
:
class Book < ActiveRecord::Base
scope :confirmed, :conditions => { :confirmed => true }
scope :published, :conditions => { :published => true }
end
Rails 2 için ihtiyacınız var named_scope
.
:published
kapsam Book.published
yerine
size verir Book.find(:published => true)
.
Rails 3'ten beri, bu yöntemleri aralarındaki dönemlerle birleştirerek 'zincirleyebilirsiniz', böylece yukarıdaki kapsamlarla artık kullanabilirsiniz Book.published.confirmed
.
Bu yöntemle, sorgu gerçek sonuçlar gerekinceye kadar yürütülmez (tembel değerlendirme), bu nedenle 7 kapsam birlikte zincirlenebilir, ancak performans sorunlarının 7 ayrı sorgu yürütmesini önlemek için yalnızca 1 gerçek veritabanı sorgusuyla sonuçlanabilir.
Bir tarih veya user_id gibi geçirilen bir parametreyi kullanabilirsiniz (çalışma zamanında değişecek ve bu nedenle bu 'tembel değerlendirmeye' ihtiyaç duyacak bir lambda ile, şöyle:
scope :recent_books, lambda
{ |since_when| where("created_at >= ?", since_when) }
# Note the `where` is making use of AREL syntax added in Rails 3.
Son olarak, varsayılan kapsamı aşağıdakilerle devre dışı bırakabilirsiniz:
Book.with_exclusive_scope { find(:all) }
veya daha iyisi:
Book.unscoped.all
herhangi bir filtreyi (koşulları) veya sıralamayı (sırala) devre dışı bırakır.
İlk sürümün Rails2 + 'da çalıştığını, ikinci sürümün (paketlenmemiş) yalnızca Rails3 + için olduğunu unutmayın.
Yani
... eğer düşünüyorsan, hmm, yani bunlar tıpkı yöntemler gibi ..., evet, tam olarak bu kapsamların ne olduğu!
Sahip olmak gibi def self.method_name ...code... end
ama her zaman olduğu gibi yakut ile işleri sizin için kolaylaştırmak için küçük sözdizimsel kısayollar (veya 'şeker') vardır!
Aslında 1 grup 'hepsi' kayıtlarında çalıştıklarından Sınıf düzeyinde yöntemlerdir.
Ancak formatları değişiyor, raylar 4 ile #scope çalıştırılabilir bir nesneyi geçmeden kullanımdan kaldırılıyor. Örneğin kapsam: kırmızı; burada (renk: 'kırmızı') olarak değiştirilmelidir scope :red, -> { where(color: 'red') }
.
Yan not olarak, yanlış kullanıldığında, varsayılan _scope yanlış kullanılabilir / kötüye kullanılabilir.
Bu esas olarak , sadece sonuçları sipariş etmek için kullanılmaktansa where
, varsayılan seçimi ( varsayılan için kötü bir fikir ) sınırlamak (filtrelemek) gibi eylemler için ne zaman kullanıldığına ilişkindir.
İçin where
seçimleri, sadece düzenli adlandırılmış kapsamları kullanın. ve mesela, sorguda o kapsamını eklemek Book.all.published
nerede published
adlandırılmış kapsamı.
Sonuç olarak, kapsamlar gerçekten harika ve 'şişman model ince kontrol cihazı' DRYer yaklaşımı için işleri modele doğru itmenize yardımcı oluyor.
default_scope { order("#{table_name}.created_at DESC") }
?
default_scope { order(created_at: :desc) }
4.2.6
göre sıralamak gibi görünüyor updated_at
değil created_at
.
updated_at
varsayılan olarak sıralama ? : - |
Michael'ın yukarıdaki mükemmel cevabına hızlı bir güncelleme.
Rails 4.0+ için, sıralamanızı aşağıdaki gibi bir bloğa koymanız gerekir:
class Book < ActiveRecord::Base
default_scope { order('created_at DESC') }
end
Sipariş ifadesinin kıvırcık ayraçlarla gösterilen bir bloğa yerleştirildiğine dikkat edin.
Bunu değiştirdiler çünkü dinamik bir şeye geçmek çok kolaydı (şimdiki zaman gibi). Bu, blok çalışma zamanında değerlendirildiği için sorunu giderir. Bir blok kullanmazsanız bu hatayı alırsınız:
Bir blok olmadan #default_scope çağrısı desteği kaldırıldı. Örneğin
default_scope where(color: 'red')
, yerine kullanındefault_scope { where(color: 'red') }
. (Alternatif olarak self.default_scope'u yeniden tanımlayabilirsiniz.)
As @Dan aşağıda onun yorumunda bahseder, bu gibi daha rubyish sözdizimi yapabilirsiniz:
class Book < ActiveRecord::Base
default_scope { order(created_at: :desc) }
end
veya birden çok sütunla:
class Book < ActiveRecord::Base
default_scope { order({begin_date: :desc}, :name) }
end
Teşekkürler @ Dan !
default_scope { order(created_at: :desc) }
benim gibi, raylardaki sql sözdizimini en aza indirmeye çalışıyorsunuz gibi yazılabilir . <br/> Sipariş vermek için birden fazla sütununuz varsa ve yeni sözdizimini kullanmak istiyorsanız, böyle bıyıklarda sütunlardefault_scope { order({begin_date: :desc}, :name) }
Varsayılan sıralama düzenini uygulamak için default_scope kullanabilirsiniz http://api.rubyonrails.org/classes/ActiveRecord/Scoping/Default/ClassMethods.html
default_scope
ondan elden geçirildi, çünkü o sayfadaki, ActiveRecord::Base
içine ActiveRecord::Scoping::Default::ClassMethods
( api.rubyonrails.org/classes/ActiveRecord/Scoping/Default/... )