验证时如何迭代取值:实现新Bid价格高于对应Item所有历史出价的校验
你收到的类型报错是因为IHP中通过get #bids item拿到的默认是QueryBuilder "bids"类型(用来构造SQL查询的构造器),不是已经加载的Bid列表,所以不能直接当做列表做模式匹配。
解决方案
两个问题可以合并解决,提供两种常用实现方案:
方案1:数据库聚合查询(推荐,性能最优)
直接通过SQL查询计算对应Item的最高出价,不需要拉取全量出价数据,空出价时自动返回0:
-- 查询指定Item的最高出价,无出价时返回0 getHighestBidPrice :: Id "items" -> IO Int getHighestBidPrice itemId = do -- 直接在数据库层做max聚合查询 maxPriceMaybe <- query @Bid |> filterWhere (#itemId, itemId) |> selectMax #price |> fetchOne -- Nothing对应无出价场景,返回默认值0 pure $ maybe 0 id maxPriceMaybe
对应的校验逻辑修改如下:
validateIsPriceAboveOtherBids bid = do highestBidPrice <- getHighestBidPrice (get #itemId bid) bid |> validateField #price (isGreaterThan highestBidPrice) |> pure
方案2:应用层计算最大值(适合出价量级小的场景)
如果需要先拿到全量Bid列表做其他处理,可以先加载关联的出价数据,再做列表模式匹配:
validateIsPriceAboveOtherBids bid = do -- 先fetchItem,再预加载关联的bids,拿到[Bid]类型的列表 item <- fetch (get #itemId bid) >>= fetchRelated #bids let bids = get #bids item highestBidPrice = getHighestBidPrice bids bid |> validateField #price (isGreaterThan highestBidPrice) |> pure where getHighestBidPrice :: [Bid] -> Int getHighestBidPrice [] = 0 -- 空列表默认值0 getHighestBidPrice bids = bids |> map (get #price) |> maximum
内容的提问来源于stack exchange,提问作者amitaibu
相关产品推荐
相关产品推荐

