Here's the PostsController
from the blog example in the IHP guide:
instance Controller PostsController where
action PostsAction = do
posts <- query @Post
|> orderByDesc #createdAt
|> fetch
render IndexView { .. }
action NewPostAction = do
let post = newRecord
render NewView { .. }
action ShowPostAction { postId } = do
post <- fetch postId
>>= pure . modify #comments (orderByDesc #createdAt)
>>= fetchRelated #comments
render ShowView { .. }
action EditPostAction { postId } = do
post <- fetch postId
render EditView { .. }
action UpdatePostAction { postId } = do
post <- fetch postId
post
|> buildPost
|> ifValid \case
Left post -> render EditView { .. }
Right post -> do
post <- post |> updateRecord
setSuccessMessage "Post updated"
redirectTo EditPostAction { .. }
action CreatePostAction = do
let post = newRecord @Post
post
|> buildPost
|> ifValid \case
Left post -> render NewView { .. }
Right post -> do
post <- post |> createRecord
setSuccessMessage "Post created"
redirectTo PostsAction
action DeletePostAction { postId } = do
post <- fetch postId
deleteRecord post
setSuccessMessage "Post deleted"
redirectTo PostsAction
Let's suppose I have a controller where one of the action definitions is getting really long and I'd like to maybe put it in a separate file.
Just as an example, let's try to move this one out:
action PostsAction = do
posts <- query @Post
|> orderByDesc #createdAt
|> fetch
render IndexView { .. }
I tried to setup a separate standalone function:
actionPostsAction = do
posts <- query @Post
|> orderByDesc #createdAt
|> fetch
render IndexView { .. }
Then my action definition could just be:
action PostsAction = actionPostsAction
However, when I setup the standalone function I get some errors reported in vscode:
What's a good way to factor out an action? Is there a way to do this?
The guide has a section on Controller & Actions but I didn't notice anything there about splitting out actions. Let me know if I missed something there or if there's another place which talks about this.
I think this is one of the cases where an explicit type signature is necessary, this should work:
actionPostsAction
:: ( ?context :: ControllerContext
, ?modelContext :: ModelContext
, ?theAction :: PostsController
)
=> IO ()
actionPostsAction = do
posts <- query @Post
|> orderByDesc #createdAt
|> fetch
render IndexView { .. }