2010-07-06 62 views
1

我正在嘗試爲我的rails應用程序進行日誌記錄,並且在rails中使用哲學時遇到了一些困境。我的應用程序有Link模型,has_manyHit S:Rails中的關注點困境的分離

class Link < AR::Base 
    has_many :hits 
end 

class Hit < AR::Base 
    belongs_to :link 
end 

現在每個鏈接被打的時候,我打電話hit!方法來記錄的鏈接請求(保持控制器瘦我做出型肥胖):

class LinksController < ApplicationController 
    def hit 
    link = Link.find(params[:id]) 
    link.hit!(request) 
    end 
end 

class Link < AR::Base 
    def hit!(request) 
    params = extract_data_from_request(request) 
    hits.create(params) 
    end 
end 

現在,這裏是我困惑的地方。我想記錄與request對象(如遠程IP,引用,用戶代理等)的數據,所以我需要傳遞請求對象到模型,但我認爲這不符合「分離關注」和模糊MVC設計模式中的責任線(當然,糾正我,如果我錯了)。另外,如果我將創建在控制器本身Hit對象,然後我在做瘦模特和脂肪控制器:

class LinksController < ApplicationController 
    def hit 
    hit_params = extract_data_from_request(request) 
    Hit.create(hit_params.merge(:link_id => params[:id]) 
    end 
end 

雖然後一種情況下,使測試更容易(我並不需要模擬模型請求規格) - 它看起來不正確。

對此有任何意見 - 非常感謝。

P.S.方法被放置在需要的地方。它返回Hit對象所需屬性的散列。

回答

2

就我個人而言,我會過於擔心這些事情太多。

命中的概念與網站或Web應用程序非常相關,就像(HTTP)請求的概念一樣。胖控制器的反模式更多的是包含冗長的控制器操作,這些操作包含ActiveRecord查找語句和業務邏輯(通常以if/elsif/else塊爲特徵),可以輕鬆提取到模型中。

控制器有一定的編排責任。在一箇中創建一個對象並不是一個可怕的罪行。畢竟,我們一直在做我們的create行動。

2

是的,我同意約翰。請求的概念通常是一個'控制器事件',但在這種情況下,您的模型是建模請求,所以在這種情況下它絕對在模型領域。有效地,一旦請求對象跨越控制器到模型的邊界,它就是另一個對象,沒有特殊的屬性:它不再需要獲取和響應html請求的過程,它只是一個對象,你可以隨心所欲地做任何事情。

不過,有一點需要注意的是,在ruby參數是通過引用傳遞的。這意味着您在您的模型中操作的請求對象是與在控制器中處理的對象相同的對象。我可能會過度偏執(或者只是明顯的錯誤),但是您可能想將它的副本傳遞給模型而不是實際的請求本身。即

class LinksController < ApplicationController 
    def hit 
    link = Link.find(params[:id]) 
    link.hit!(request.dup) 
    end 
end 
+0

好的答案,但不需要'重複'請求'只要它沒有被修改,它不應該。 – PhilT 2016-03-18 16:49:28

+0

就像我說的,偏執狂:)我擔心有人(例如我)可能會遲一些來,並對模型方法內的請求對象進行一些更改,而不會意識到後果。但是,不是絕對必要的。 – 2016-03-18 16:51:00

+1

然後你的代碼就會被'dup'調用所拋棄。這被稱爲防禦性編程。你最好明智地使用'freeze' – PhilT 2016-03-18 16:54:57