2011-02-02 14 views
66

Ho recentemente iniziato uno stage. Il mio datore di lavoro usa il rubino su rotaie e spesso incontro una nuova sintassi che devo cercare per capire. Ho cercato su google una buona spiegazione di named_scope, ma quello che ho trovato finora è per la maggior parte post sul blog che lo elogia, piuttosto una definizione o un'introduzione dritta.Che cos'è scope/named_scope nelle rotaie?

Che cosa è esattamente named_scope (ora chiamato semplicemente scope) in ruby ​​on rails?

+0

possibile duplicato di [Qual è il significato dell'ambito con nome in Rails?] (Http://stackoverflow.com/questions/2919730/whats-the-significance-of-named-scope-in-rails) – jdl

+2

Questo post del blog è stato prezioso per me quando ho imparato gli scope nominati: http://ryandaigle.com/articles/2008/8/20/named-scope-it-s-not-just-for-conditions-ya-know –

+0

Link per ryandaigle ora trovato qui: http://archives.ryandaigle.com/articles/2008/8/20/named-scope-it-s-not-just-for-conditions-ya-know –

risposta

152

Un ambito è un sottoinsieme di una raccolta. Sembra complicato? Non lo è. Immagina:

Hai utenti. Ora, alcuni di questi utenti sono iscritti alla tua newsletter. Hai contrassegnato coloro che ricevono una newsletter aggiungendo un campo al Database degli utenti (user.subscribed_to_newsletter = true). Naturalmente, a volte vuoi ottenere quegli utenti che sono iscritti alla tua newsletter.

Si potrebbe, naturalmente, sempre fare questo:

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

Invece di scrivere sempre questo è possibile, tuttavia, fare qualcosa di simile.

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

Se stai usando Rails 4 o più recenti, fare questo, invece:

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

questo ti permette di accedere ai vostri abbonati semplicemente facendo questo:

User.newsletter.each do #something 

Questo è un esempio molto semplice ma in generale gli ambiti possono essere strumenti molto potenti per semplificare il tuo lavoro.

controlla questo link: API Description

+6

Posso chiederti quali sono i vantaggi di questo definendo un metodo nella classe utente chiamato 'subscribedUsers'? per esempio. 'def self.subscribedUsers self.where (: subscribed_to_newsletter => true) end – redroot

+3

@redroot il vantaggio è che la sintassi 'scope' è molto più pulita, si ottiene lo stesso risultato ma con una sola riga –

+1

si possono concatenare gli ambiti – nir0

6

Il modo migliore per capire sui dettagli è quello di andare a documentazione API.

Otterrete i dettagli completi e i modi in cui possiamo utilizzare gli ambiti.

API Documentation of Scope

20

portata nel record attivo è come i metodi di classe, ma tornano oggetto rapporto che significa che si può chiamare un altro ambito o di un metodo di interrogazione record attivo su di esso.

Ad esempio, se si dispone di un modello di Zombie (tabella zombie) con i metodi portata di seguito menzionate,

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

e si chiama

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

Si traduce al di sotto in SQL,

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

Esempio precedente basato su rotaia 4 sintassi

4

Scoping consente di specificare query di uso comune (può essere considerato come collegamento per query lunghe o utilizzate più frequentemente) a cui è possibile fare riferimento come chiamate di metodo sugli oggetti o sui modelli dell'associazione.Con questi ambiti, è possibile utilizzare tutti i metodi precedentemente trattati come dove, si unisce e include. Tutti i metodi di scope saranno restituiscono un oggetto ActiveRecord :: Relation che consentirà di richiamare ulteriori metodi (come altri ambiti).

Per definire una semplice applicazione, si utilizza il metodo di applicazione all'interno della classe, passando la query che vorremmo eseguire quando questo ambito si chiama:

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

Questo è esattamente lo stesso come definente una metodo di classe, e che si utilizza è una questione di preferenze personali:

class Article < ActiveRecord::Base 
    def self.published 
    where(published: true) 
    end 
end 

segui il seguente link per la descrizione completa con l'esempio. Spero che questo ti possa aiutare.

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

+0

Non è * identico alla definizione di un metodo di classe *. I metodi di classe restituiscono 'nil' in alcuni casi, e quindi non concatenabili per determinate condizioni. –

0

semplice spiegazione.

Immagina di avere un modello: Persona. I modelli devono essere singolari.

Ora si immagina:

  • desidera che tutte le persone nel mondo che hanno i capelli rossi.
  • desidera che tutte le persone nel mondo che giocano a cricket

Si potrebbe ottenere quelle classi particolari di persone utilizzando un ambito! (per favore scusa il gioco di parole)

Ora non è stato così difficile?

Problemi correlati