0

我想保留通常會被銷燬的舊記錄。例如,用戶加入一個項目,稍後將被踢出。我想保留user_project記錄,並將記錄標記爲非活動狀態。爲此,我在每個模型中使用狀態屬性來定義每條記錄的當前狀態。使用狀態屬性來維護Rails中的舊記錄

幾乎所有我的「查詢」只需要「活動」記錄,狀態== 1的記錄,並且我想使用ActiveRecord助手(find_by等)。我不想添加所有「find_by」我使用「_and_state」來查找只有活動的記錄。

這是我現在有:

u = UserProject.find_by_user_id_and_project_id id1, id2 

這是我將有這樣每個查詢的所有車型:

u = UserProject.find_by_user_id_and_project_id_and_state id1, id2, 1 

什麼是實現這個最乾淨的方式(狀態維護和更乾淨的查詢代碼)?

class UserProject < ActiveRecord::Base 
    scope :active, where(:state => 1) 
end 

和 「過濾器」 您的疑問:

回答

2

在模型UserProject創建範圍

u = UserProject.active.find_by_user_id_and_project_id id1, id2 

,如果你 「幾乎八方通」 只能查詢活動UserProject S,你可以定義此範圍爲default_scope並使用unscoped如果要查詢所有記錄:

class UserProject < ActiveRecord::Base 
    default_scope where(:state => 1) 
end 

u = UserProject.find_by_user_id_and_project_id id1, id2 # only active UserProjects 
u = UserProject.unscoped.find_by_user_id_and_project_id id1, id2 # all states 
+0

如果我在ActiveRecord類中創建範圍,它是否適用於所有模型? – JPHorta

+1

在極少數情況下,** ALL **您的模型具有相同含義的列「狀態」,是的。但是最好聲明你自己的子類,並從這個類中派生你的模型。 –

1

我試圖將此添加到Martin的答案中,但我的編輯必須進行審查,所以儘管Martin的答案很好,但我們可以通過默認範圍的想法改進一點。默認範圍始終應用於該模型發現者將它們添加到,除非你明確關閉默認範圍:

class UserProject < ActiveRecord::Base 
    default_scope where(:state => 1) 
end 

馬丁給了就變成了這個例子:

u = UserProject.find_by_user_id_and_project_id id1, id2 

在這種情況下,即使沒有指定你想狀態== 1,你只會得到活動記錄。如果這幾乎總是您想要的,那麼使用默認範圍將確保您不會在代碼中的某處意外地忽略'.active',這可能會創建一個難以發現的錯誤。

如果您指定的默認範圍是這樣的:

default_scope :conditions => {:state => 1} 

然後新建UserProjects將已經狀態設置爲1,您無需顯式設置。

這裏有一個默認的作用域的詳細信息:http://apidock.com/rails/ActiveRecord/Base/default_scope/class

以下是如何暫時關閉它們,當你需要找到的所有記錄: http://apidock.com/rails/ActiveRecord/Scoping/Default/ClassMethods/unscoped