2017-05-19 4 views
1

die effizienter/besser in einer Rails-Anwendung ist:Definieren von Klassenmethoden basierend auf Datenbankinhalte - Leistung

class Foo < ApplicationRecord 
    Foo.pluck(:name).each do |name| 
    define_singleton_method(name) { Foo.find_by(name: name) } 
    end 
end 

oder Ausführung des Codes in einem Initialisierer (config/initializers/foo.rb):

Foo.pluck(:name).each do |name| 
    Foo.define_singleton_method(name) { Foo.find_by(name: name) } 
end 

oder vielleicht etwas anderes?

Hinweis: Foo Instanzen werden nur einmal in einem Initialisierer erstellt. Sie werden von keinem Benutzer in der Anwendung geändert.

Ich tue dies für jeden Foo Rekord

def self.bar 
    find_by(name: 'bar') 
end 

Schreiben zu vermeiden.

+0

BTW: Die Singleton-Methode erstellt eine neue Foo-Instanz jedes Mal, wenn die Methode aufgerufen wird. Betrachte 'Foo.each {| e | define_singleton_method (e.name) {e}} '. – sschmeck

+0

Ich bin immer noch am kämpfen, um zu sehen, warum Sie dies tun möchten, es sei denn, Sie haben eine sorgfältige Kontrolle über die Datenbankwerte Sie können am Ende wichtige Methoden überschreiben. – max

Antwort

1

, die effizienter ist/besser in einer Rails-Anwendung

Initializer Option aus dem gleichen Grund Sie in Ihrem note erwähnt. Da sich Ihre Foo nicht ändern wird, ist es besser, sie vorher zu initialisieren, anstatt sie unterwegs zu initialisieren/zu definieren, wenn Sie die Klasse aufrufen.

Ein weiterer guter Grund, um die erste Option zu vermeiden, ist, dass es einen DB-Aufruf macht. Nehmen wir an, Sie haben eine Methode in dieser Klasse, die nichts mit generierten Methoden zu tun hat, sie würde sie dennoch definieren und Ihnen eine db-Transaktion kosten.

Erste Lösung wäre gut, wenn es dynamisch gewesen wäre. Ich habe mit ähnlichen Fällen gearbeitet und sie arbeiten für mich gut.

Der einzige Nachteil, den ich mit der initializers Lösung denken kann, ist die Bootzeit Ihrer App. Wenn foo eine große Anzahl von Spalten hat, fügt es nach der Bereitstellung/dem Neustart einige Sekunden in Ihrer Boot-Zeit hinzu. was ich denke, ist akzeptabel gegen diese paar Sekunden multipliziert mit der Anzahl der Anrufe, die Sie an Foo Klasse machen.

Verwandte Themen