2012-07-26 9 views
6

In ActiveRecord gibt es eine Klassenmethode, um einen Standardbereich anzugeben. Zum Beispieldefault_scope in Sequel

class User < ActiveRecord::Base 
    default_scope where(:deleted => false) 
end 

User.all # => SELECT * FROM users WHERE deleted = 0; 

Wie kann ich dies in Sequel::Model tun?

EDIT:

Nach einigen googeln fand ich schließlich einige nützliche Informationen.

User.all # => SELECT * FROM `users` WHERE (`deleted` IS FALSE) 

By the way: Das entspricht unscoped ist unfiltered:

User.unfiltered.all # => SELECT * FROM `users` 

Aber, gibt es ein Problem

class User < Sequel::Model 

    # Define some "scopes" (filters on the dataset) 
    dataset_module do 
    def existing 
     filter(deleted: false) 
    end 

    def active 
     filter(disabled: false) 
    end 
    end 

    # This is the equivalent to a default_scope. Set one of the datasets 
    # as the default dataset for this model. 
    set_dataset(self.active) 
end 

Die erzeugte Abfrage dann wie folgt aussieht . Wenn Sie versuchen, einen Benutzer zu aktualisieren, der aus einem ungefilterten Dataset stammt, versucht er, den Benutzer mithilfe des angegebenen Datasets zu aktualisieren.

User.create(disabled: true, deleted: true) 
User.all # => [] 
u = User.unfiltered.first # => Given user 
u.disabled = false 
u.save # => UPDATE users SET ... WHERE (disabled IS FALSE AND id = 1) 
# => Sequel::NoExistingObject: Attempt to update object did not result in a single row modification 

Also bin ich wieder am Anfang. Irgendeine Abhilfe für dieses?

Antwort

5

Die beste Problemumgehung besteht darin, das Problem zu vermeiden, indem Sie keinen Standardbereich haben. In den meisten Fällen ist ein Standardbereich eine schlechte Idee. Wenn Sie möchten, dass die meisten Abfragen einen Bereich verwenden, wenden Sie den Bereich manuell in diesen Abfragen an, verwenden Sie keinen Standardbereich und versuchen Sie, den Bereich in anderen Abfragen zurückzusetzen. Ein Standardbereich ist nur dann sinnvoll, wenn alle Ihrer Abfragen diesen Bereich verwenden.

Sie können dies auch durch Unterklassen bearbeiten (Benutzer ist nicht beschränkt, ActiveUser < Benutzer ist Bereich). Ich finde jedoch, dass der explizite Scoping-Ansatz besser funktioniert.

Alles, was gesagt wird, wenn Sie wirklich einen Standardbereich verwenden möchten, die folgenden das Problem umgehen kann eine Modellinstanz außerhalb der Standardbereich des Modells der Aktualisierung:

User.instance_dataset.unfiltered!