2012-07-29 28 views
7

Actualmente, al guardar, estoy tratando de verificar si un registro cae en un 'alcance' particular. Este 'alcance' realmente es solo algunos argumentos guardados para una llamada .where. También con este 'alcance' solo estoy comprobando los valores del objeto, nunca cómo se relaciona con otros objetos en la base de datos, por lo que consultar la base de datos siempre será exagerado si tiene sentido.Verifique para ver si un objeto de registro activo particular está en un 'alcance' particular

sólo he sido capaz de llegar a la solución por debajo de

begin 
    result = self.class.where(scope).find(self.id) 
rescue 
    result = false 
end 

El problema con esto es que tengo para consultar la base de datos a pesar de que ya tengo el registro, y tengo que ejecutar esto no solo antes de guardar, pero después de guardar para verificar los valores que era y los valores que serán después de guardar, porque no hay forma de consultar la base de datos para la versión actualizada si no se ha guardado.

Puede haber varias de estas comprobaciones, por lo que me gustaría evitar tener que hacerlo dos veces, y también tener que consultar la base de datos muchas veces, incluso si finalmente estoy buscando algo por ID.

La única otra solución en la que he podido pensar sería tener un método que de alguna forma traduce la llamada where a un proceso que devuelve un valor booleano cuando pasa un objeto. El único problema con esto es la traducción, de alguna manera tendría que funcionar con el adaptador de registro activo que se está utilizando, lo que parece un proyecto completo para sí mismo. Entonces, ¿alguien sabe de alguna manera de hacer esto, o de una joya que ayudaría?

PD Obteniendo el 'alcance' de la memoria caché, así que no puedo guardarlo como un proceso porque no puedes poner procs en la memoria caché con Rails.

+1

Puede ser útil proporcionar un ejemplo concreto del registro que está guardando, las condiciones del alcance y por qué está tratando de hacer esto. Puede haber una mejor manera de hacer lo que sea exactamente lo que estás tratando de hacer. – deefour

+0

El registro podría ser cualquier cosa y también el alcance siempre y cuando no requiera comparación con ninguna otra cosa en la base de datos, se supone que es reutilizable sin importar la configuración. Sin embargo, es para un sistema de almacenamiento en caché. Así que, básicamente, si el registro antes o después de guardar cae en el "alcance" de un caché, ese caché se elimina. Es para páginas realmente complicadas que desea almacenar en caché, pero no desea caducar a menos que el registro actualizado pueda ser parte de la caché. – rovermicrover

+0

misma pregunta aquí: http://stackoverflow.com/questions/1255815/check-if-model-instance-falls-within-named-scope-in-rails – voondo

Respuesta

5

primero puede mejorar su primera solución un poco

result = self.class.where(scope).exists?(self.id) 

si no desea comprobar la base de datos, ¿por qué no acaba de comprobar si los atributos de tu objeto tiene los valores del alcance? si su alcance es

class.where(:attr1 => value1, :attr2 => value2, :attr3 => value3) 

entonces usted puede hacer

result = self.attr1 == value1 and self.attr2 == value2 and self.attr3 == value3 
+0

La primera parte ayuda mucho, no sé por qué ¡No pensé en eso, me di mucha importancia en eso! La segunda parte del problema es que no quiero restringir las instrucciones where a la configuración del cohete hash. Por ejemplo, en un proyecto que estoy haciendo el alcance es si la entrada se publicó entre dos fechas, y con eso terminaría teniendo que analizar lo que se le dio. ¡Aunque eso realmente me ayuda a comenzar a pensar en la dirección correcta! ¡Gracias! – rovermicrover

3

Si sus alcances son simples, es probable que desee para evitar la duplicación de código. Mi solución le permite llamar al model.active? para saber si una instancia pertenece al alcance, y Model.active para encontrar todos los registros que coinciden con el alcance. model.active? no implica ninguna consulta de base de datos.

considerar la adición de este a config/initializers/scope_and_method.rb:

require 'active_record/named_scope' 

module ActiveRecord::NamedScope::ClassMethods 
    def scope_and_method field, *values 
    field = field.to_sym 
    values.each do |value| 
     named_scope value.to_sym, :conditions => {field => value} 
     define_method "#{value}?" do 
     send(field.to_sym) == value 
     end 
    end 
    end 
end 

Uso:

scope_and_method :state, 'active', 'inactive' 

Obras como si se tratara:

named_scope :active, :conditions => {:state => 'active'} 
named_scope :inactive, :conditions => {:state => 'inactive'} 

def active? 
    state == 'active' 
end 

def inactive? 
    state == 'inactive' 
end 

Ésta es una solución para Rails 2.3. Esto necesita una afinación muy pequeña para Rails 3 y 4. (named_scope ->scope) Lo comprobaré pronto.

Cuestiones relacionadas