2012-07-26 13 views
6

W ActiveRecord istnieje metoda klasy default_scope do określenia zakresu domyślnego. Na przykład:default_scope w Sequel

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

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

Jak mogę to zrobić w Sequel::Model?

EDIT:

Po pewnym googling I w końcu znaleźć kilka przydatnych informacji.

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 

Wygenerowany zapytania wtedy wygląda to tak:

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

Nawiasem mówiąc: Odpowiednikiem unscoped jest unfiltered:

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

Ale, jest jeden problem . Jeśli spróbujesz zaktualizować użytkownika z niefiltrowanego zestawu danych, spróbuje on zaktualizować użytkownika przy użyciu danego zestawu danych.

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 

Więc wróciłem na początku. Jakiekolwiek obejście tego problemu?

Odpowiedz

5

Najlepszym sposobem na obejście problemu jest uniknięcie domyślnego zakresu. W większości przypadków domyślny zakres jest złym pomysłem. Jeśli chcesz, aby większość zapytań używała zakresu, zastosuj zakres ręcznie w tych zapytaniach, nie używaj zakresu domyślnego i spróbuj wycofać zakres w innych kwerendach. Domyślny zakres ma sens tylko wtedy, gdy wszystkie zapytania będą używać tego zakresu.

Można również obsłużyć to poprzez podklasę (użytkownik nie ma dostępu do zakresu, użytkownik ActiveUser < użytkownik ma zasięg). Uważam jednak, że podejście jawne scoping działa lepiej.

Wszystko, co zostało powiedziane, jeśli naprawdę chcesz, aby użyć domyślnego zakresu dodaje może obejść problem z aktualizacją instancji modelu poza domyślnym zakresem modelki:

User.instance_dataset.unfiltered! 
Powiązane problemy