2015-12-17 72 views
9

對於在Phoenix控制器某些查詢,這裏有兩種方案我我應該在Elixir Phoenix的Controller還是Model中使用Ecto.Repo?

計劃1:

defmodule Demo.UserController do 
    # ... 
    def index do 
    # This is just for example 
    # The point is Repo in used here 
    Repo.all(User) 
    end 
end 

計劃2:

defmodule Demo.User do 
    # ... 
    def all do 
    # Put all Repo API and building query logic in Model 
    Repo.all(__MODULE__) 
    end 
end 

我喜歡,因爲在大多數計劃2在這種情況下,我可以將所有關於在Model中獲取數據的邏輯放在一起

但我發現官方指導使用計劃1(docs/model)和鳳凰默認代碼alias Repo的控制器,而不是模型(web/web.ex

哪一個更好?爲什麼?

回答

16

您應該將您的回購電話保留在您的控制器內。如果你的邏輯很複雜,那麼你應該考慮將邏輯移出到它自己的服務模塊中。

您應該將您的模型函數視爲純粹的(不受副作用),因此它們只應該對數據起作用。因此,例如,你可以有:

def alphabetical(query) 
    order_by(query, [u], u.name) 
end 

但你不應該有:

def alphabetical(query) 
    order_by(query, [u], u.name) 
    |> Repo.all 
end 

這是因爲查詢是純粹的數據,調用Repo.all有副作用(會關閉到數據庫中),所以它屬於你的控制器。

+0

嗨,我有關於這個問題的另一個問題。如果我在控制器中放置回購呼叫,如何測試模型?就像你的例子一樣,我應該使用Repo插入一些記錄然後做測試(它看起來像一個集成測試)或只是測試'order_by'的結果?順便說一句,我不知道如何測試'order_by'的結果。 –

+1

在Phoenix編程中,我們建議開發人員在測試/模型中包含兩個測試文件:user_test.exs和user_repo_test.exs。第一個可以測試變更集和不需要存儲庫的所有內容。優點是你可以在頂部運行「async:true」。另一個需要存儲庫,它可能是您測試複雜查詢的地方。這完全取決於你想寫哪種測試。 –

相關問題