2012-07-26 10 views
6

En ActiveRecord hay un método de clase default_scope para especificar un alcance predeterminado. Por ejemplodefault_scope en Secuela

class User < ActiveRecord::Base 
    default_scope where(:deleted => false) 
end 

User.all # => SELECT * FROM users WHERE deleted = 0; 

¿Cómo se puede hacer esto en Sequel::Model?

EDIT:

Después de algunas google final encontré alguna información útil.

class User < Sequel::Model 

    # Define some "scopes" (filters on the dataset) 
    dataset_module do 
    def existing 
     filter(deleted: false) 
    end 

    def active 
     filter(disabled: false) 
    end 
    end 

    # This is the equivalent to a default_scope. Set one of the datasets 
    # as the default dataset for this model. 
    set_dataset(self.active) 
end 

La consulta generada tendrá el aspecto siguiente:

User.all # => SELECT * FROM `users` WHERE (`deleted` IS FALSE) 

Por cierto: El equivalente a unscoped es unfiltered:

User.unfiltered.all # => SELECT * FROM `users` 

Pero, hay un problema . Si intenta actualizar un usuario que obtuvo de un conjunto de datos sin filtrar, intenta actualizar al usuario utilizando el conjunto de datos dado.

User.create(disabled: true, deleted: true) 
User.all # => [] 
u = User.unfiltered.first # => Given user 
u.disabled = false 
u.save # => UPDATE users SET ... WHERE (disabled IS FALSE AND id = 1) 
# => Sequel::NoExistingObject: Attempt to update object did not result in a single row modification 

Así que estoy de vuelta al principio. ¿Alguna solución para esto?

Respuesta

5

La mejor solución es evitar el problema al no tener un alcance predeterminado. En la mayoría de los casos, un alcance predeterminado es una mala idea. Si desea que la mayoría de sus consultas usen un ámbito, luego aplique el alcance manualmente en esas consultas, no use un alcance predeterminado e intente retroceder el alcance en otras consultas. Un alcance predeterminado solo tiene sentido si todos de sus consultas usarán ese alcance.

También puede manejar esto mediante la creación de subclases (El usuario no tiene un alcance, ActiveUser < El usuario tiene el alcance). Sin embargo, creo que el enfoque de alcance explícito funciona mejor.

dicho todo esto, si realmente desea utilizar un ámbito predeterminado, lo siguiente puede evitar el problema de la actualización de una instancia de modelo fuera del ámbito predeterminado del modelo:

User.instance_dataset.unfiltered! 
Cuestiones relacionadas