2014-01-08 40 views
2

好吧,所以實際上有幾個問題,我會盡力描述他們每個人與另一個孤立,但從某種意義上說,他們都是相關的。如何在一個處理程序中使用Auth和PostgresqlSimple?

我想插入一個用戶ID,我想從AuthManager得到。好吧,這很公平,我們可以使用currentUser,然後做一些maybe巫毒來獲得實際的unUid。但接下來是問題何時開始。好了,所以我們要使用execute到exute查詢:

execute "INSERT INTO events(title,recurring) VALUES(?,?);" (eventname,recurring) 

熱潮。好的,那麼在做cabal install時,它會失敗,說沒有可用於我聲明的類型的HasPostgres實例。因爲我的處理程序的類型是...-> ...-> Handler App (AuthManager App),所以非常合理。 這是第一個問題:我不知道如何正確地創建實例,以便類型正確正如我試過,只是複製Application.hs中的初始實例根本沒有幫助我們。

這會將我們帶到嘗試尋找替代解決方案時出現的其他問題。所以我嘗試的解決方案是用with pg $ execute呼叫代替execute呼叫。這有以下結果:

Couldn't match type `App' with `AuthManager App' 
Expected type: Handler App (AuthManager App) GHC.Int.Int64 
    Actual type: Handler App App GHC.Int.Int64 

所以再次,無濟於事。接下來我嘗試的是刪除(AuthManager App)類型,然後用App代替它,然後我可以用with auth $ call替換AuthManager調用。然後我意識到這也不是解決方案,因爲一旦你得到AuthManager,你需要從每個調用它的函數中刪除它。

我需要一些幫助來解決這個問題。我能以某種方式解除此類問題以解決此問題嗎?或者,這個問題的解決方案是什麼?


編輯

好了,所以我試圖刪除AuthManager App出我喜歡的類型,所以我可以使用Postgres的畢竟。現在,這並沒有像預期的那樣順利。下一部分來源於由Snap init產生一個普通的應用程序:

handleLoginSubmit :: Handler App App() 
handleLoginSubmit = 
with auth $ loginUser "login" "password" Nothing 
      (\_ ->handleLogin err) (handleFoo) 
where 
    err = Just "Unknown user or password" 

好了,所以這兩個handleLoginhandleFoo現在有類型Handler App App(),但尚未哈斯克爾抱怨,預計類型Handler App (AuthManager App)()

Couldn't match type `App' with `AuthManager App' 
Expected type: Handler App (AuthManager App)() 
    Actual type: Handler App App() 


--Definition of App: 
data App = App 
{ _heist :: Snaplet (Heist App) 
, _sess :: Snaplet SessionManager 
, _auth :: Snaplet (AuthManager App) 
, _pg :: Snaplet Postgres 
} 
+1

你用於處理程序的簽名是什麼? – DiegoNolan

+0

@DiegoNolan,通常他們有':: Handler App(AuthManager App)()',然後在路由中添加'auth'。 – froginvasion

+1

您是否嘗試過'Handler App App()'? – DiegoNolan

回答

4

你想使用這種類型的簽名。

yourHandler :: Handler App App() 
    with pg $ execute ... 
    with auth $ loginUser ... 

with功能讓您養Handler b v功能,它只能訪問到V snaplet的數據,爲Handler b b,其獲得的一切。它唯一需要做的就是從b到v的鏡頭。

2

我寫了一個snaplet基於Postgres Snaplet,所以這應該適合你。

instance HasPostgres (Handler App (AuthManager App)) where 
    getPostgresState = withTop pg get 

,然後用簽名的路線:

myRoute :: Handler App (AuthManager App)() 
相關問題