是否有使用 Haskell Persistent 执行模型验证的便捷方法?

Posted

技术标签:

【中文标题】是否有使用 Haskell Persistent 执行模型验证的便捷方法?【英文标题】:Is there convenient way to perform model validations with Haskell Persistent? 【发布时间】:2014-01-06 18:17:37 【问题描述】:

有没有办法在每个update/replaceinsert 之前执行自定义验证(某种挂钩)并在验证失败时返回一条消息?就像可以在ActiveModel 中完成一样。

我可以只写一个验证函数,但我需要重写我更新或插入这个模型的所有地方。

【问题讨论】:

【参考方案1】:

AFAIK persistent 没有任何用于验证的内置钩子,这是我使用的(结合 yesod 的 i18n):

-- | Represents an entity that has validation logic
class Validatable e where

    -- | A set of validations and error messages for a
    --   given entity.
    validations :: e -> [(Bool, AppMessage)]
    validations _ = []

    -- | Validate an entity and respond with a Bool wrapped in
    --   a writer with potential error messages. By default this
    --   makes use of @validations e@
    validate :: e -> (Bool, [AppMessage])
    validate e = runWriter $ foldM folder True $ validations e
      where
        folder a (v, m) | v = return $ a && True
                        | otherwise = tell [m] >> return False

并定义您的验证:

instance Validatable Stock where
    validations e = [ ((0<) . stockInventory $ e, MsgPurchaseErrorInventoryNegative)
                    , ((0<) . unMoney . stockPrice $ e, MsgPurchaseErrorPriceNegative)
                    , (maybe True ((0<) . unMoney) . stockCostPrice $ e, MsgPurchaseErrorCostPriceNegative)
                    , ((2<=) . length . stockName $ e, MsgPurchaseErrorNameTooShort)
                    ]

然后在你的处理程序中:

let (isvalid, errors) = validate s
unless isvalid $ invalidArgsI errors

【讨论】:

以上是关于是否有使用 Haskell Persistent 执行模型验证的便捷方法?的主要内容,如果未能解决你的问题,请参考以下文章

“类型变量不明确”在 Haskell Yesod 中使用 Persistent

Haskell Persistent:可以按包含指定值的字段选择所有行

Haskell Persistent 上的 CRUD 模式

Haskell的Persistent sometmes返回500内部服务器错误

使用 Persistent 输入与数据库的关系

Haskell Persistent Library - 如何从我的数据库中获取数据到我的前端?