Überwiegendes in Activerecord „finden“ die DRY Weg
-
09-06-2019 - |
Frage
Ich habe ein paar Modelle, die benutzerdefinierte haben müssen Bedingungen an sie gestellt finden. Zum Beispiel, wenn ich eine Kontakt Modell haben, wird jedes Mal Contact.find genannt, möchte ich die Kontakte wieder beschränken, dass nur auf das Konto in Gebrauch gehören.
Das fand ich über Google (die ich ein wenig angepasst haben):
def self.find(*args)
with_scope(:find => { :conditions => "account_id = #{$account.id}" }) do
super(*args)
end
end
Dies funktioniert gut, bis auf ein paar Gelegenheiten, bei denen account_id mehrdeutig ist so angepasst ich es an:
def self.find(*args)
with_scope(:find => { :conditions => "#{self.to_s.downcase.pluralize}.account_id = #{$account.id}" }) do
super(*args)
end
end
Das funktioniert auch toll, aber ich will es trocken sein. Jetzt habe ich ein paar verschiedenen Modelle, die ich diese Art von Funktion soll verwendet werden. Was ist der beste Weg, dies zu tun?
Wenn Sie antworten, bitte den Code umfasst unsere Köpfe das metaprogramming Rubin-fu erfassen zu helfen.
(Ich bin mit Rails v2.1)
Lösung
Sie sagen uns nicht, welche Version von Schienen Sie verwenden [bearbeiten - es ist auf Schienen 2.1 somit folgende Ratschläge voll funktionsfähig ist], aber ich würde empfehlen Sie das folgende Formular nutzen statt Überlastung finden sich:
account.contacts.find(...)
Dies wird den Fund in einem Bereich automatisch umbrochen, wo die Benutzer-Klausel enthalten ist (da Sie die account_id haben ich nehme an, Sie das Konto haben irgendwo in der Nähe)
Ich schlage vor, Sie in den folgenden Ressourcen auf Bereiche überprüfen
Andere Tipps
Jean Rat ist Klang. Angenommen, Ihre Modelle wie folgt aussehen:
class Contact < ActiveRecord::Base
belongs_to :account
end
class Account < ActiveRecord::Base
has_many :contacts
end
Sie sollten die contacts
Vereinigung des laufenden Kontos verwenden, um sicherzustellen, dass Sie nur scoped auf dieses Konto, Contact
Aufzeichnungen immer etwa so:
@account.contacts
Wenn Sie weitere Bedingungen an Ihre Kontakte Abfrage hinzufügen möchten, können Sie angeben, sie finden mit:
@account.contacts.find(:conditions => { :activated => true })
Und wenn Sie sich ständig finden für aktivierte Benutzer abfragen, können Sie es in einem benannten Umfang Refactoring:
class Contact < ActiveRecord::Base
belongs_to :account
named_scope :activated, :conditions => { :activated => true }
end
Was Sie würde dann wie folgt verwenden:
@account.contacts.activated
eine spezifische Antwort auf Ihr Problem geben, ich würde vorschlagen, dass das oben genannte Verfahren in ein Modul zu bewegen durch die Modelle in Frage einbezogen werden; so müssten Sie
class Contact
include NarrowFind
...
end
PS. achten Sie auf SQL des account_id entkommen, sollten Sie vielleicht die :conditions=>[".... =?", $account_id]
Syntax verwenden.