2011-02-02 32 views
66

Kısa bir süre önce staja başladık. İşverenim, raylarda yakut kullanıyor ve sık sık anlamak istediğim yeni sözdizimi ile karşılaşıyorum. Named_scope'un iyi bir açıklaması için etrafta dolaştım, ancak şu ana kadar bulduğum şey çoğunlukla blog yazılarıdır, bunun yerine yüksek bir tanım ya da tanıtım.Raylarda kapsam/named_scope nedir?

tam olarak raylar üzerinde yakut içinde named_scope (şimdi sadece kapsam olarak adlandırılır) nedir?

+0

olası bir kopyası [Rails içinde adlandırılmış kapsamın önemi nedir?] (Http://stackoverflow.com/questions/2919730/whats-the-significance-of-named-scope-in-rails) – jdl

+2

Bu blog yazısı adlandırılmış kapsamları öğrenirken benim için çok değerliydi: http://ryandaigle.com/articles/2008/8/20/named-scope-it-s-not-just-for-conditions-ya-know –

+0

Ryandaigle bağlantısı şimdi bulundu burada: http://archives.ryandaigle.com/articles/2008/8/20/named-scope-it-s-not-just-for-conditions-ya-know –

cevap

152

Kapsam, koleksiyonun bir alt kümesidir. Sesler karmaşık mı? Öyle değil. Bunu düşünün:

Kullanıcılarınız var. Şimdi, bu Kullanıcılardan bazıları bülteninize abone oluyor. Kullanıcı Veritabanına bir alan ekleyerek bir bülten alan kullanıcıları işaretlediniz (user.subscribed_to_newsletter = true). Doğal olarak, bazen bülteninize abone olan Kullanıcıları almak istersiniz.

Elbette, her zaman yapabilirsiniz:

User.where(subscribed_to_newsletter: true).each do #something 

Yerine, her zaman, ancak, böyle bir şey yapabileceğini bu yazı.

#File: users.rb 
class User < ActiveRecord::Base 
    scope :newsletter, where(subscribed_to_newsletter: true) 
    #yada yada 
end 

Eğer Rails 4 veya yeni kullanıyorsanız, bunun yerine bunu:

User.newsletter.each do #something 

Bu:

#File: users.rb 
class User < ActiveRecord::Base 
    scope :newsletter, -> { where(subscribed_to_newsletter: true) } 
    #yada yada 
end 

Bu sadece bu yaparak aboneler erişmesine olanak tanır çok basit bir örnektir, ancak genel kapsamlarda işinizi kolaylaştıracak çok güçlü araçlar olabilir. Bu bağlantıyı dışarı

Kontrol: API Description

+6

Bunun avantajlarının ne olduğunu sorabilir miyim? Kullanıcı Sınıfında 'subscribedUsers' adında bir yöntem tanımlamak? Örneğin. 'def self.subscribedUsers self.where (: subscribed_to_newsletter => true) end – redroot

+3

@redroot avantajı' kapsam 'sözdizimi çok daha temizdir, aynı sonucu elde edersiniz ama sadece bir satır –

+1

zincir kapsamları – nir0

6

iyi yolu detayları hakkında anlamak için API Belgeleri gitmektir.

Sen tam ayrıntıları ve biz Falınızı kullanabilirsiniz yollarını alırsınız. Aktif kaydındaki

API Documentation of Scope

20

kapsamı sınıf yöntemleri gibi ancak bunun üzerine başka bir kapsamı veya etkin kayıt sorgulama yöntemi çağrı anlamına gelir ilişki nesnesi geri gönderecekti. Aşağıda belirtilen kapsam yöntemleri ile bir zombi modeli (zombiler tablo),

class Zombie 
    scope :rotting, -> { where(rotting: true) } 
    scope :fresh, -> { where('age < ?', 25) } 
    scope :recent, -> { order(:created_at, :desc) } 
end 

Ve varsa

Örneğin,,

O SQL altına çevirir

Zombie.rotting.fresh.recent.limit(3) 

çağrı

select "zombies.*" from "zombies" where "zombies"."rotting" = 't' and (age<20) order by create_at desc limit 3 

Yukarıdaki örnek raylara dayanmaktadır 4 sözdizimi

4

Kapsam Belirleme sık kullanılan sorguları (uzun veya sık kullanılan sorgularda kısayol olarak düşünülebilir) belirtmenize izin verir; bunlar ilişkilendirilen nesneler veya modellerde yöntem çağrıları olarak adlandırılabilir.Bu kapsamlar ile daha önce kapsanan, dahil olan ve içerdiği gibi her yöntemi kullanabilirsiniz. Tüm kapsam yöntemleri , ActiveRecord :: Relation nesnesini döndürür; bu, üzerinde başka yöntemler (diğer kapsamlar gibi) çağrılmasına olanak tanır.

class Article < ActiveRecord::Base 
    scope :published, -> { where(published: true) } 
end 

Bu tam bir tanımlama aynıdır:

biz bu kapsam çağrıldığında çalıştırmak istediğiniz sorguyu geçen sınıf içinde kapsam yöntemini kullanın basit kapsamını tanımlamak için
class Article < ActiveRecord::Base 
    def self.published 
    where(published: true) 
    end 
end 

örnekle tam açıklaması için aşağıdaki bağlantıyı takip edin: kullanmak sınıf yöntemi ve hangi kişisel tercih meselesidir. Umarım bu sana yardımcı olmuştur.

http://guides.rubyonrails.org/active_record_querying.html

+0

Bu bir * sınıf yöntemini tanımlamakla aynı değildir *. Sınıf yöntemleri birkaç durumda 'nil 'döndürür ve bu nedenle belirli koşullar için zincirlenebilir değildir. –

0

Basit açıklama.

Bir modeliniz olduğunu hayal edin: Person. Modeller tekil olmalı.

Şimdi hayal:

  • kırmızı saçlı Dünyadaki bütün insanlar istiyorum.
  • istiyorum Bir kapsamını kullanarak insanların özellikle bu sınıfları alabilir

kriket oynamak dünyadaki tüm insanlar! (lütfen mazereti belirtin)

Bu çok zor olmadı mı?