2012-07-29 7 views
7

Derzeit auf speichere ich, wenn ein aufgezeichnetes fällt in einen bestimmten ‚Umfang‘ zu überprüfen, mich versuche zu sehen. Dieser 'Bereich' ist wirklich nur ein paar gespeicherte Argumente für einen .where-Aufruf. Außerdem überprüfe ich mit diesem 'scope' immer nur die Werte des Objekts, nicht jedoch, wie es sich auf andere Objekte in der Datenbank bezieht, also wird die Abfrage der Datenbank immer überkillt, wenn das sinnvoll ist.überprüfen Sie, ob ein bestimmtes Active Record-Objekt in einem ‚Anwendungsbereich‘ Besonderes Ist

Ich habe nur in der Lage gewesen, mit der untenen Lösung mit diesem

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

Die Frage zu kommen, ist, dass ich die Datenbank abzufragen habe, obwohl ich bereits den Rekord habe, und ich habe dies nicht laufen nur vor dem Speichern, aber nach dem Speichern, um die Werte und die Werte nach dem Speichern zu überprüfen, da es keine Möglichkeit gibt, die Datenbank nach der aktualisierten Version abzufragen, wenn sie nicht gespeichert wurde.

Es kann eine Reihe von diesen Prüfungen geben, so möchte ich es vermeiden, es zweimal zu tun, und auch die Datenbank mehrmals abfragen, auch wenn ich letztlich nur etwas nach ID suchen.

Die einzige andere Lösung, die ich habe, ein Verfahren zu haben, wäre denken konnte, dass einige, wie das übersetzt, wo in einem proc aufrufen, die einen boolean zurück, wenn ein Objekt übergeben. Das einzige Problem, das damit zu tun hat, ist, wie man mit dem aktiven Plattenadapter arbeiten muss, der wie ein ganzes Projekt aussieht. Kennt also jemand einen Weg, dies zu tun, oder eines Edelsteins, der helfen würde?

PS ich den ‚Umfang‘ aus dem Cache bekommen, damit ich es nicht als proc sparen, weil Sie nicht Procs in den Cache mit Rails setzen können.

+1

Es kann hilfreich sein, ein konkretes Beispiel für die Aufzeichnung von den Verhältnissen aussehen Anwendungsbereich Sie speichern, zu liefern, und warum dies zu tun, Sie versuchen. Es könnte einen besseren Weg geben, um genau das zu erreichen, was Sie gerade tun. – deefour

+0

Der Datensatz könnte alles sein und so könnte der Bereich, solange es keinen Vergleich zu irgendetwas anderem in der Datenbank erfordert, es sollte wiederverwendbar sein, egal, die Einrichtung. Es ist jedoch für ein Caching-System. Wenn der Datensatz vor oder nach dem Speichern in den Cache-Bereich fällt, wird der Cache gelöscht. Es ist für wirklich komplizierte Seiten, die Sie zwischenspeichern möchten, aber nicht ablaufen möchten, außer der aktualisierte Datensatz könnte Teil des Cache sein. – rovermicrover

+0

gleiche Frage hier: http://stackoverflow.com/questions/1255815/check-if-model-instance-falls-withi-named-scope-in-rails – voondo

Antwort

5

erste können Sie Ihre erste Lösung verbessern ein wenig

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

wenn Sie wollen die Datenbank nicht überprüfen, warum Sie nicht nur überprüfen, ob Ihr Objekt die Attribute die Werte des Anwendungsbereichs hat? wenn Ihr Anwendungsbereich

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

ist, dann können Sie

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

Der erste Teil hilft eine Menge, ich weiß nicht warum Daran habe ich nicht gedacht, mein Kopf war weit! Der zweite Teil der Frage ist, dass ich die WHERE-Anweisungen nicht auf die Hash-Rakete beschränken möchte. Zum Beispiel bei einem Projekt, das ich mache, ist der Umfang, wenn der Eintrag zwischen zwei Daten veröffentlicht wurde, und damit würde ich am Ende herausfinden müssen, was gegeben wurde. Aber das hilft mir wirklich, in die richtige Richtung zu denken! Vielen Dank! – rovermicrover

3

tun, wenn Ihre Bereiche einfach sind, möchten Sie wahrscheinlich Code Doppelarbeit zu vermeiden. Meine Lösung ermöglicht es Ihnen, model.active? zu anrufen zu wissen, ob eine Instanz zum Umfang gehört, und Model.active alle Datensätze zu finden, den Umfang entsprechen. model.active? beinhaltet keine Datenbankabfragen. Dies ist eine Lösung für Schienen 2,3

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

def active? 
    state == 'active' 
end 

def inactive? 
    state == 'inactive' 
end 

:

denken Sie daran, diese zu 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 

Verbrauch:

scope_and_method :state, 'active', 'inactive' 

Works, als ob es war. Dies erfordert eine sehr kleine Abstimmung für die Schienen 3 und 4. (named_scope ->scope) Ich werde es bald überprüfen.

Verwandte Themen