2009-10-30 8 views
43

dado un modelo con default_scope para filtrar todas las entradas obsoletas:Rails: ¿Por qué está protegido con_s_sclusivo_scopio? ¿Alguna buena práctica sobre cómo 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 

Ahora quiero conseguir cualquier billete . En este caso, with_exclusive_scope es el camino a seguir, pero ¿está protegido este método? Sólo esto funciona:

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

Tipo de un truco, ¿no? Entonces, ¿cuál es la forma correcta de usar? Especialmente cuando se trata de asociaciones, se está haciendo aún peor (dado un usuario tiene muchas entradas):

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

Eso es lo que fea !!! - ¡No puede ser el camino de los carriles !?

+1

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

Respuesta

164

FYI para aquellos que buscan la forma Rails3 de hacer esto, puede utilizar el método de unscoped: "¿qué es el uso de los carriles` default_scope` tan mala idea"

Ticket.unscoped.all 
+2

¡Esto es un salvavidas, gracias! – njorden

+2

¡Santa mierda!¡Ojalá estuviera más cerca de la cima! – Ramy

+56

Tenga cuidado con el uso del método no combinado, ya que eliminará todas las restricciones de consulta que se hayan agregado anteriormente. Por ejemplo, suponiendo que author.books.all devuelve todos los libros por un autor (ordenado por id a través de default_scope), author.books.unscoped.order ('books.title'). Todos devolverán TODOS los libros, independientemente del autor como el unscoped elimina la restricción que books.author_id == author.id – douglasr

20

Debe encapsular el método protegido dentro de un método de modelo, algo así como:

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

hm bien, bien tengo sentido, lo probaré ... ¡Gracias! – RngTng

+5

"with_exclusive_scope" está en desuso. En los rieles 3 y 4, use "sin cobertura" en su lugar. Para más detalles y ejemplos, eche un vistazo a: http://github.com/rails/rails/commit/bd1666ad1de88598ed6f04ceffb8488a77be4385 – Kote

33

Evitar si es posible default_scope. Creo que realmente debería volver a preguntarse por qué necesita un default_scope. Contrarrestar un default_scope suele ser más complicado de lo que vale y solo debe usarse en casos excepcionales. Además, usar default_scope no es muy revelador cuando se accede a las asociaciones de tickets fuera del modelo de ticket (por ejemplo, "Llamé al account.tickets. ¿Por qué mis tickets no están allí?"). Esta es parte de la razón por la cual with_exclusive_scope está protegido. Deberías probar algunos syntactic vinegar cuando lo necesites.

Como alternativa, use una joya/complemento como pacecar que agrega automáticamente útiles_costos útiles a sus modelos, proporcionándole un código más revelador en todas partes. Por ejemplo:

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 

También se puede decorar su modelo de usuario necesarios para depurar el código anterior:

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 al margen: También, considere el uso de un nombre de columna de fecha y hora más idiomática como ends_at en lugar de end_date.

+1

thx, sí sé que default_scope es malo, pero en mi caso específico, que es un poco más complejo que el dado uno, esta es la mejor solución (por ahora) – RngTng

+0

Más sobre 'default_scope': ¿Por qué se recomienda usar el default_scope? (http://stackoverflow.com/questions/25087336/why-is-using-the-rails-default-scope-often-recommend-against) – wrtsprt

Cuestiones relacionadas