2015-10-06 148 views
2

在我的Ruby on Rails項目中,我有一個郵件程序,它基本上爲給定用戶準備系統中發生的事情的每日摘要。在郵件收發控制器中,我根據一些常見模式(在特定日期內,未由該用戶創作,未標記等)收集來自各種模型的所有相關記錄,並且從模型到模型的細微差異。Dry up Rails Active記錄查詢條件

這裏涉及半數模型(和計數),其中大多數對於某些事情(例如發佈日期或者是否由管理員標記項目)具有統一的列名稱。因此,進入查詢的'where大部分是相同的。條件有細微差別,但至少有2或3個條件完全相同。我很容易假設模型之間可能會有更類似的情況,因爲我們剛開始使用該功能,但尚未弄清數據的最終形狀。

我基本上鍊接'where'調用每個模型。它激怒我有6行代碼如此接近彼此,跨越到我的代碼編輯器的權利,但仍然如此相似。我很害怕這樣的想法,即在某個時候,我們將不得不改變其中一種「核心」條件,並一次性用多行代碼進行轉換。

我想做的事情是將一組進入每個查詢的核心條件移入某種Proc或其他類型,然後在每個模型(如示波器)上簡單地調用它,然後繼續'where '與模型特定的條件鏈。很像每個型號上的scope

我正在努力的是如何做到這一點,同時保持郵件內的代碼。我當然知道,我可以在一個關注點內聲明一個複雜的範圍,然後將它混合到我的模型中,並開始每個具有該範圍的查詢。然而,這種方式邏輯將遠離郵件程序,進入未知領域的模型問題,並且它將使每個模型變得複雜,目前只需要一個龐大系統中的一個小郵件程序。此外,對於某些查詢,查詢需要User模型的一組詳細信息,而且我不希望每個模型都處理User。

我喜歡作用域的活動記錄模式通過lambda表達式定義方式(如scope :pending, -> { where(approved: [nil, false]) }),並一直在尋找一種方式來使用類似的語法模型類(外面,我的郵件方法裏面可能有tap或類似的東西),但我還沒有找到任何這種方法的好例子。

那麼,是否有可能實現?我可以在我的郵件收集方法中收集核心'where''內部的某些變量的電話,並將它們應用於多個模型,但仍然可以繼續連接where鏈?

回答

1

阿雷爾的美麗,背後的ActiveRecord查詢生成技術,是這一切都完全可組合的,用普通的紅寶石。

我理解你的問題,這是你想要做的嗎?

def add_on_something(arel_scope) 
    arel_scope.where("magic = true").where("something = 1") 
end 


add_on_something(User).where("more").order("whatever").limit(10) 

add_on_something(Project.where("whatever")).order("something") 

只是普通的ruby方法會做到這一點,你不需要一個特殊的AR功能。因爲AR範圍已經可組合。

+0

謝謝,看起來像它。我在尋找一個不必要的複雜問題的答案,當然一個簡單的本地方法會有很大的幫助。 – user20532

1

你可以這樣做:

@report_a = default_scope(ModelA) 
@report_b = default_scope(ModelB) 

private 
def default_scope(model) 
    model. 
    where(approved: [nil, false]). 
    order(:created_at) 
    # ... 
end