2009-10-30 9 views
43

Dato un modello con default_scope per filtrare tutte le voci obsolete:Rails: Perché con_esclusivo_scope è protetto? Qualche buona pratica su come usarlo?

# == Schema Information 
# 
# id   :integer(4)  not null, primary key 
# user_id  :integer(4)  not null, primary key 
# end_date :datetime   

class Ticket < ActiveRecord::Base 
    belongs_to :user 
    default_scope :conditions => "tickets.end_date > NOW()" 
end 

Ora voglio ottenere qualsiasi biglietto. In questo caso with_exclusive_scope è la strada da percorrere, ma questo metodo è protetto? Solo questo funziona:

Ticket.send(:with_exclusive_scope) { find(:all) } 

una specie di hack, non è? Allora, qual è il modo giusto per usare? Soprattutto quando si tratta di associazioni, si sta facendo ancora peggio (dato un utente ha molti biglietti):

Ticket.send(:with_exclusive_scope) { user.tickets.find(:all) } 

Ecco così brutto !!! - non può essere il binario !?

+1

http://stackoverflow.com/questions/25087336/why-is-using-the-rails-default-scope-often-recommend-against – MrYoshiji

risposta

164

FYI per chi cerca il modo Rails3 di fare questo, è possibile utilizzare il metodo unscoped: "perché sta usando le rotaie` default_scope` una cattiva idea"

Ticket.unscoped.all 
+2

Questo è un vero toccasana, grazie! – njorden

+2

santo schifo!Vorrei che questo fosse più vicino alla cima! – Ramy

+56

Attenzione però all'utilizzo del metodo senza ambito poiché rimuoverà tutti i vincoli di query che potrebbero essere stati aggiunti in precedenza. Ad esempio, supponendo che author.books.all restituisca tutti i libri di un autore (ordinati tramite id tramite default_scope), author.books.unscoped.order ('books.title'), tutti restituiranno effettivamente TUTTI i libri indipendentemente dall'autore come unscoped rimuove il vincolo che books.author_id == author.id – douglasr

20

Devi incapsulare il metodo protetto all'interno di un metodo di modello, qualcosa di simile:

class Ticket < ActiveRecord::Base 
    def self.all_tickets_from(user) 
    with_exclusive_scope{user.tickets.find(:all)} 
    end 
end 
+0

hm ok, beh, in un certo senso, farò un tentativo .. Grazie! – RngTng

+5

"with_exclusive_scope" è deprecato. Nelle rotaie 3 e 4, invece, usi "non spopolato". Per maggiori dettagli ed esempi dare un'occhiata a: http://github.com/rails/rails/commit/bd1666ad1de88598ed6f04ceffb8488a77be4385 – Kote

33

Evitare, se possibile default_scope. Penso che dovresti davvero chiederti perché hai bisogno di uno default_scope. Contrastare un default_scope è spesso più complicato di quanto valga e dovrebbe essere usato solo in rari casi. Inoltre, l'utilizzo di default_scope non è molto significativo quando si accede alle associazioni di ticket al di fuori del modello Ticket (ad esempio "Ho chiamato . Perché i miei biglietti non sono lì?"). Questo è uno dei motivi per cui with_exclusive_scope è protetto. Dovresti assaggiare un po 'di syntactic vinegar quando devi usarlo.

In alternativa, utilizzare un gemma/plug-in come pacecar che aggiunge automaticamente named_scopes ai modelli in modo da ottenere un codice più rivelatore ovunque. Per esempio:

class Ticket < ActiveRecord::Base 
    include Pacecar 
    belongs_to :user 
end 

user.tickets.ends_at_in_future # returns all future tickets for the user 
user.tickets     # returns all tickets for the user 

È inoltre possibile decorare il vostro modello User per rendere il più pulito codice di cui sopra:

Class User < ActiveRecord::Base 
    has_many :tickets 

    def future_tickets 
    tickets.ends_at_in_future 
    end 
end 

user.future_tickets # returns all future tickets for the user 
user.tickets  # returns all tickets for the user 

Nota a margine: Inoltre, considerare l'utilizzo di un nome di colonna datetime più idiomatica come ends_at invece di end_date.

+1

thx, sì, so default_scope è male, ma nel mio caso specifico, che è un po 'più complesso come il dato uno, questa è la soluzione migliore (per ora) – RngTng

+0

Altro su 'default_scope': Perché si raccomanda l'uso di default_scope contro? (http://stackoverflow.com/questions/25087336/why-is-using-the-rails-default-scope-often-recommend-against) – wrtsprt

Problemi correlati