问题
I would like to extract a database field (Text) and pass it as an argument to another function from a Handler. However, I run into Type errors. Completely made up example so may feel a bit contrived but should illustrate the issue I am having.
Person
name Text
Car
personId PersonId
name Text
type Text
I would like to get a Car entity and then find the corresponding Person. Get his name and then pass it as an argument. Something like:
data MyD = MyD { input1 :: Int}
entryForm :: Text -> Form MyD -- Update: Removed the incorrect extra parameter
entryForm n1 = renderDivs $ MyD
<$> areq intField n1 Nothing
My get handler looks like:
getInputR :: CarId -> Handler Html
getInputR carId = do
car <- runDB $ get404 carId
pid <- carPersonId car
name <- getPName pid
(widget, enctype) <- generateFormPost $ entryForm name
defaultLayout $ do
$(widgetFile "my_template")
where
getPName pid = do
person <- runDB $ get404 pid
personName person
I get an error saying:
Couldn't match expected type `HandlerT App IO t0'
with actual type `KeyBackend
persistent-1.2.1:Database.Persist.Sql.Types.SqlBackend Person'
In the return type of a call of `carPersonId'
In a stmt of a 'do' block: pid <- carPersonId car
What am I doing wrong?
Thanks!
回答1:
Try changing
pid <- carPersonId car
name <- getPName pid
to
name <- getPName $ carPersonId car
The value returned from your runDB
call is not inside the handler monad so you don't need to use the arrow syntax to access it.
For the second error, the issue is similar: The getPName
function's return type is in the Handler monad since it uses runDB
, so you need to use return
to put the value into the monad:
getPName pid = do
person <- runDB $ get404 pid
return $ personName person
来源:https://stackoverflow.com/questions/17891488/extracting-database-field-values-inside-a-handler