Frage

Ich habe ein baumartiges Modell, bei dem in alle Situationen aber ein , ich möchte, die Ergebnisse zu Umfang, um nur die Wurzeln zurückzukehren.

class Licence < ActiveRecord::Base
  default_scope :conditions => { :parent_licence_id, nil }

  belongs_to :parent_licence, :class_name => 'Licence'
  has_many :nested_licences, :class_name => 'Licence',
           :foreign_key => 'parent_licence_id', :dependent => :destroy
end

class User < ActiveRecord::Base
  has_many :licences
end

Mit default_scope wie eine wunderbare Idee schien, weil die verschiedenen Modelle, die Assoziationen Lizenz haben (es etwa 4 von ihnen sind) und auch beliebigen Code mit find (), würde nichts Besonderes tun muss. Der Grund ist es nicht eine wunderbare Idee ist, dass der Standardbereich gilt auch für die has_many, die Ergebnisse in nie die Kinder zu finden. Aber die has_many ist die nur Ort, der den Rahmen sprengen muss aus, so weit wie „default“ Verhalten geht, ich denke, das default_scope durchaus sinnvoll ist.

So gibt es eine gute Möglichkeit, dieses spezielle Problem zu umgehen?

Hier ist eine, die ich bin nicht allzu gern, weil es verwendet SQL für eine fast triviale Abfrage:

has_many :nested_licences, :class_name => 'Licence', :dependent => :destroy,
  :finder_sql => 'SELECT l.* FROM licences l WHERE l.parent_licence_id = #{id}',
  :counter_sql => 'SELECT COUNT(l.*) FROM licences l WHERE l.parent_licence_id = #{id}'

Alternativ ist es eine Möglichkeit, einen benannten Rahmen eine Vereinigung aus dem Modell zu bewerben? z.B. etwas entlang der Linien von diesem Unsinn-Code:

class Licence < ActiveRecord::Base
  named_scope :roots, :conditions => { :parent_licence_id, nil }

  belongs_to :parent_licence, :class_name => 'Licence'
  has_many :nested_licences, :class_name => 'Licence',
           :foreign_key => 'parent_licence_id', :dependent => :destroy
end

class User < ActiveRecord::Base
  has_many :licences, :scope => :roots   # a :scope option doesn't really exist
end

Ich weiß, ich kann dies auch tun:

class Licence < ActiveRecord::Base
  named_scope :roots, :conditions => { :parent_licence_id, nil }

  belongs_to :parent_licence, :class_name => 'Licence'
  has_many :nested_licences, :class_name => 'Licence',
           :foreign_key => 'parent_licence_id', :dependent => :destroy
end

class User < ActiveRecord::Base
  has_many :licences, :conditions => { :parent_licence_id, nil }
end

Aber das ist wirklich nicht sehr trocken ist. Eigentlich statt Licence.roots.find() jede einzelne Abfrage durch Licence.find() zu tun hat, ist nicht sehr trocken entweder, um ehrlich zu sein. Es ist nur für einen Fehler zu fragen vor, wenn der Umfang nicht verwendet wird.

War es hilfreich?

Lösung

Versuchen Licence.unscoped.find() mit

btw - Die Dokumentation für ActiveRecord::Base.unscoped sagt, dass unscoped mit einer benannten scope Methode Verkettungs keine Wirkung.
Es wird empfohlen, die Blockform unscoped zu verwenden, da mit einem benannten unscoped scope Verkettungs nicht funktioniert. Wenn „gesendet“ (unten) ist ein named_scope die beiden folgenden Anweisungen sind die gleichen.

Message.unscoped.sent
Message.sent  

Schienen FYI 2 hat auch with_exclusive_scope, die hilfreich sein können.

Andere Tipps

Können Sie keinen Gebrauch von der :conditions Option über die Assoziation machen? So etwas wie folgt aus:

has_many :nested_licences, :class_name => 'Licence',
         :dependent => :destroy, :conditions => "parent_licence_id = #{id}" 
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top