2012-07-29 12 views
7

Attualmente in fase di salvataggio sto cercando di verificare se una registrazione cade in un particolare "ambito". Questo 'ambito' è in realtà solo alcuni argomenti salvati per una chiamata .where. Inoltre con questo 'scope' sto verificando sempre solo i valori dell'oggetto, non sempre come si rapporta ad altri oggetti nel database, quindi interrogare il database sarà sempre eccessivo se questo ha senso.Verifica se un oggetto record attivo particolare si trova in un particolare "ambito"

Sono stato solo in grado di venire con la soluzione qui di seguito

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

Il problema con questo è che ho per interrogare il database, anche se ho già il record, e devo correre questo non solo prima di salvare, ma dopo il salvataggio, verificare i valori che erano e i valori che sarà dopo il salvataggio, perché non c'è modo di interrogare il database per la versione aggiornata se non è stato salvato.

Ci possono essere un certo numero di questi controlli, quindi vorrei evitare di doverlo fare due volte e anche dover interrogare il database più volte, anche se alla fine sto solo cercando qualcosa con ID.

L'unica altra soluzione che ho potuto pensare sarebbe di avere un metodo che alcuni traducono la chiamata where in un proc che restituisce un valore booleano quando ha passato un oggetto. L'unico problema è quello di tradurre in qualche modo il modo di lavorare con l'adattatore di registrazione attivo utilizzato, che sembra un intero progetto a sé stante. Quindi qualcuno sa di un modo per farlo, o di una gemma che potrebbe aiutare?

PS Ho ottenuto il 'scope' dalla cache, quindi non posso salvarlo come un proc perché non puoi mettere proc nella cache con Rails.

+1

Potrebbe essere utile fornire un esempio concreto del record che si sta salvando, quali sono le condizioni dell'oscilloscopio e perché si sta tentando di farlo. Potrebbe esserci un modo migliore per andare su qualunque cosa sia esattamente quello che stai cercando di fare. – deefour

+0

Il record potrebbe essere qualsiasi cosa e così potrebbe essere l'ambito finché non richiede il confronto con qualsiasi altra cosa nel database, si suppone che sia riutilizzabile indipendentemente dal set up. È però per un sistema di memorizzazione nella cache. Quindi in pratica se il record prima o dopo il salvataggio cade nello "scope" di una cache che viene cancellata dalla cache. Si tratta di pagine molto complicate che si desidera memorizzare nella cache, ma che non vogliono scadere a meno che il record aggiornato non possa essere parte della cache. – rovermicrover

+0

stessa domanda qui: http://stackoverflow.com/questions/1255815/check-if-model-instance-falls-within-named-scope-in-rails – voondo

risposta

5

prima è possibile migliorare la prima soluzione un po '

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

se non si vuole controllare il database, perché non solo verificare se gli attributi del vostro oggetto ha i valori del campo di applicazione? se il vostro scopo è

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

allora si può fare

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

La prima parte aiuta molto, non so perché Non ci ho pensato, ho messo la testa in fondo! Nella seconda parte il problema è che non voglio limitare le istruzioni where al solo set di razzi hash. Per esempio su un progetto che sto facendo lo scopo è se la voce è stata pubblicata tra due date, e con quella avrei finito per dover analizzare ciò che è stato dato. Anche se questo mi aiuta davvero a cominciare a pensare nella giusta direzione! Grazie! – rovermicrover

3

Se gli ambiti sono semplici, probabilmente si vuole evitare la duplicazione del codice. La mia soluzione consente di chiamare model.active? per sapere se un'istanza appartiene all'ambito e Model.active per trovare tutti i record corrispondenti all'ambito. model.active? non implica alcuna query di database.

considerare l'aggiunta di questo 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 

Usage:

scope_and_method :state, 'active', 'inactive' 

Opere come se fosse:

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

def active? 
    state == 'active' 
end 

def inactive? 
    state == 'inactive' 
end 

Questa è una soluzione per Rails 2.3. Ciò richiede una sintonizzazione molto piccola per Rails 3 e 4. (named_scope ->scope) Verificherò presto.

Problemi correlati