分解出控制器动作
Factoring out controller actions
上下文
这是 IHP 指南 blog example 中的 PostsController
:
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
分解一个动作
假设我有一个控制器,其中一个动作定义变得非常长,我想将它放在一个单独的文件中。
举个例子,我们试着把这个移出来:
action PostsAction = do
posts <- query @Post
|> orderByDesc #createdAt
|> fetch
render IndexView { .. }
我尝试设置一个单独的独立函数:
actionPostsAction = do
posts <- query @Post
|> orderByDesc #createdAt
|> fetch
render IndexView { .. }
那么我的动作定义可以是:
action PostsAction = actionPostsAction
但是,当我设置独立函数时,我在 vscode:
中报告了一些错误
问题
分解动作的好方法是什么?有办法吗?
该指南有一节是关于 Controller & Actions 的,但我没有注意到任何关于拆分操作的内容。如果我在那里遗漏了什么或者是否有另一个地方谈论这个,请告诉我。
我认为这是需要显式类型签名的情况之一,这应该可行:
actionPostsAction
:: ( ?context :: ControllerContext
, ?modelContext :: ModelContext
, ?theAction :: PostsController
)
=> IO ()
actionPostsAction = do
posts <- query @Post
|> orderByDesc #createdAt
|> fetch
render IndexView { .. }
上下文
这是 IHP 指南 blog example 中的 PostsController
:
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
分解一个动作
假设我有一个控制器,其中一个动作定义变得非常长,我想将它放在一个单独的文件中。
举个例子,我们试着把这个移出来:
action PostsAction = do
posts <- query @Post
|> orderByDesc #createdAt
|> fetch
render IndexView { .. }
我尝试设置一个单独的独立函数:
actionPostsAction = do
posts <- query @Post
|> orderByDesc #createdAt
|> fetch
render IndexView { .. }
那么我的动作定义可以是:
action PostsAction = actionPostsAction
但是,当我设置独立函数时,我在 vscode:
中报告了一些错误问题
分解动作的好方法是什么?有办法吗?
该指南有一节是关于 Controller & Actions 的,但我没有注意到任何关于拆分操作的内容。如果我在那里遗漏了什么或者是否有另一个地方谈论这个,请告诉我。
我认为这是需要显式类型签名的情况之一,这应该可行:
actionPostsAction
:: ( ?context :: ControllerContext
, ?modelContext :: ModelContext
, ?theAction :: PostsController
)
=> IO ()
actionPostsAction = do
posts <- query @Post
|> orderByDesc #createdAt
|> fetch
render IndexView { .. }