Я пытаюсь объединить этот Heist tutorial и этот postgresql-simple tutorial.Используйте результаты postgresql-simple в шаблоне Heist
Я пробовал делать различные варианты этого.
splice :: C.Splice IO
splice = do
projects <- query_ "SELECT * FROM projects"
C.manyWithSplices C.runChildren projectSplice $ return (projects :: [Project])
where
projectSplice = do
"title" ## (C.pureSplice . C.textSplice $ title)
"description" ## (C.pureSplice . C.textSplice $ description)
Но я продолжал получать эту ошибку.
No instance for (HasPostgres (HeistT IO IO))
arising from a use of 'query_'
Possible fix:
add an instance declaration for (HasPostgres (HeistT IO IO))
In a stmt of a 'do' block:
projects <- query_ "SELECT * FROM projects"
In the expression:
do { projects <- query_ "SELECT * FROM projects";
C.manyWithSplices C.runChildren projectSplice
$ return (projects :: [Project]) }
Я не знаю, как реализовать эту декларацию экземпляра, и я до сих пор не полностью понимаю монады. Я не уверен, что я даже на правильном пути.
EDIT: Благодаря @mightybyte для его ответа, я придумал это.
projectSplice = do
"title" ## (C.pureSplice . C.textSplice $ title)
"description" ## (C.pureSplice . C.textSplice $ description)
splice :: C.Splice (Handler App App)
splice = C.manyWithSplices C.runChildren projectSplice $ lift $ query_ "SELECT * FROM projects"
getHeistState heistConfig = liftIO $ either (error "Heist Init failed") id <$> (runEitherT $ initHeist heistConfig)
getBuilder heistState = maybe (error "Render template failed") fst $ C.renderTemplate heistState "database"
getAllProjectsHeist :: Handler App App()
getAllProjectsHeist = do
let heistConfig = HeistConfig defaultInterpretedSplices defaultLoadTimeSplices ("project" ## splice) noSplices [loadTemplates "templates"]
heistState <- getHeistState heistConfig
builder <- getBuilder heistState
writeBS $ toByteString builder
О вашем редактировании: три последних функции могут быть ненужными. Просто используйте 'cRender' из модуля' Snap.Snaplet.Heist', чтобы получить обработчик, который вы хотите привязать к маршруту. Конечно, вы должны зарегистрировать сращивание во время фазы инициализации, используя что-то вроде 'addConfig' из' Snap.Snaplet.Heist'. (И если вы используете 'heistServe', вы также можете опустить' cRender', так как имя шаблона выводится из пути.) – danidiaz
Вы правы. Это помогло мне упростить код. Благодарю. – romc