2016-07-29 15 views
0

Ich möchte eine globale Variable speichern, damit ich nicht jedes Mal, wenn ich die Modelle referenziere, auf die Datenbank trete.Speichern einer globalen Variablen, die eine Sammlung von Modellen enthält

Sollte ich dies in einem Initialisierer tun oder gibt es einen anderen Weg?

$rules = Rule.all 

Diese Daten werden nie, wenn ich die Code-Basis ändern ändern, so dass es in Ordnung ist, nur, wenn Sie die App neu geladen aktualisiert.

Welche Optionen habe ich?

Ich glaube, ich kann dies tun auch in meinem Controller:

$rules ||= Rule.all 

Gibt es eine "best practice" in Bezug auf das?

+0

Das ist eine schlechte Idee. Nun, zuerst müssen Sie wissen, warum Sie den Wert zwischenspeichern möchten? Möchten Sie den Wert beim Hochfahren zwischenspeichern? –

+0

Wenn die Daten statisch sind, warum eine Datenbank anstelle eines einfachen Ruby-Hash oder Arrays verwenden? – meagar

+0

@ArupRakshit Ja beim Booten. – Blankman

Antwort

1

Ok, dann erstellen Sie im Verzeichnis config/initializers/ eine Datei wie load_rules.rb. Schreiben Sie so etwas wie:

ActiveSupport.on_load(:active_record) do 
    RULES = Rule.all 
end 

Verwenden Sie jetzt diese Konstante überall wo Sie verwenden möchten.

+0

Warum sollte er sogar ActiveRecord-Objekte verwenden, wenn er nichts mit der Datenbank macht? – siegy22

+0

@RaVeN Er verwendete den Begriff _model_. Die Zeile _Ich möchte eine globale Variable speichern, so dass ich nicht jedes Mal, wenn ich auf die Modelle referenziere, auf die Datenbank stoße_, ist genug, um auf diese Lösung zu schließen. Aber wie ich in deinem Antwortkommentar gesagt habe, brauchst du für statische Daten kein Modell. Ich bemerke den Design-Geruch später. –

+0

Warten Sie also, dass ein "Modell" immer ein ActiveRecord-Modell ist? – siegy22

0

Ich denke, dass Sie die Datenbank für so etwas nicht verwenden möchten. Sie sollten diese Werte als Array von Objekten speichern und verwenden Sie den Rails.app.config.x Namespace:

#app/models/rule.rb 
class Rule 
    attr_reader :name 

    def initialize(name:) 
    @name = name 
    end 
end 

und Ihre initializer:

# config/initializers/rules_initializer.rb 
Rails.application.config.x.rules = [ 
             Rule.new(name: "Admin"), 
             ... 
            ] 
+0

Dieser Ansatz erfordert eine Änderung des Codes, wenn sich der Regelsatz ändert. –

+0

Objekte zu erstellen, 'sets.rb' Datei ist gut, denke ich. –

+0

@NicNilov Wie würden Sie keinen Code ändern, wenn sich der Satz ändert? Speichern Sie es in der db? – siegy22

1

Ich würde vorschlagen, mit

so Ihr Modell aussehen würde, Low-Level-Caching in einer Methode gewickelt:

class ApplicationCotroller < ActionController::Base 
    # ... 

    def all_rules 
     Rails.cache.fetch("all_rules") do 
     Rule.all 
     end 
    end 

    # ... 
end 

Abhängig In Ihrem Anwendungsfall könnte die Methode in eine Singleton-Klasse anstatt ApplicationController oder in eine Mischung Module platziert werden.

Der Hauptvorteil dieses Ansatzes besteht darin, dass Sie die Regeln problemlos neu laden können, ohne den Server neu zu starten, indem Sie den Cacheschlüssel von der Konsole löschen. Obwohl Sie dies eindeutig als nicht-kritischen Aspekt markiert haben, denke ich, dass es etwas Bequemlichkeit hinzufügt.

+0

Ich mochte Ihren Cache-Ansatz! +1. Der Grund dafür ist, dass wir die Daten ohne Neustart aktualisieren können. Gute Idee! –

+0

Aber was ist, wenn ich es in einem anderen Kontext verwenden möchte? Sie müssen wahrscheinlich einige Arten von Initialisierungen für den globalen Zugriff verwenden. –

+1

Ja, wie ich bereits erwähnt habe, kann es je nach Anwendungsfall anderswo platziert werden, ein Initialisierer ist eine Option. –

Verwandte Themen