2012-07-26 27 views
6

在ActiveRecord中有一個default_scope類方法來指定默認範圍。例如續集中的default_scope

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

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

我該怎麼做Sequel::Model

編輯:

一些google搜索後,我終於找到一些有用的信息。

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 

生成的查詢則是這樣的:

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

順便說:相當於unscopedunfiltered

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

,有一個問題。如果您嘗試更新從未過濾數據集獲得的用戶,它會嘗試使用給定數據集更新用戶。

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 

所以我回到了開始。任何解決方法?

回答

5

最好的解決方法是通過沒有默認範圍避免問題。在大多數情況下,默認範圍是一個壞主意。如果您希望大多數查詢使用範圍,那麼在這些查詢中手動應用範圍,請勿使用默認範圍並嘗試在其他查詢中取消範圍。默認範圍只有在您的查詢的所有都使用該範圍時纔有意義。

您也可以通過繼承來處理這個問題(用戶不在作用域,ActiveUser <用戶被作用域)。但是,我發現明確的範圍界定方法效果更好。

所有這一切是說,如果你真的想使用默認的範圍,以下可能解決外部模式的默認範圍更新模型實例的問題:

User.instance_dataset.unfiltered!