2012-03-19 95 views
1

定义一些动作的关键是在这个文件:加工形式耶索德并使用输入来创建的模型

https://github.com/gdoteof/exodus/blob/42c5ee09f09dcb718fa3bdfd79bfe5182c03faaa/Handler/GamingSession.hs

,我要的总体思路是接受张贴输入,并使用该输入,并结合来自getCurrentTime的UTCTime来创建新的GamingSession。

然后将GamingSession插入到数据库中。

现在在/ session中发生的事情是一个表单发布到/ session,并预填了值。但我得到一个错误

Prelude.read:没有解析

(相关配置/路线:https://github.com/gdoteof/exodus/blob/d07bea21e7699b44739ceadf3c3a18533a9ef462/config/routes

回答

0

改变

textToKey = Key . PersistText . read . unpack 

textToKey a = fromJust . fromPathPiece $ a 

固定对我来说

0

你得到错误意味着输入并不像一个正常的整数。预填充值的实际外观是什么?来自ireq textField "player"ireq textField "table"的字符串必须为,只是包含可能用空白填充的数字。

另外,为了使处理不好的分析更容易,您应该查看safe package。这包含read(及类似函数)的一个版本,它返回Maybe,所以如果无法解析输入,则会得到一个Nothing而不是异常。

+0

值看起来像 “4f6150251c21230c78000000”,这是一个id来自mongo – geoff 2012-03-19 16:47:09

1

当我有一个持久性键的表单时,我通常更喜欢下拉菜单而不是手动输入。尝试下面的代码。另外,尝试遵循书中的惯用风格,它会有所帮助。

gs <- runInputPost $ GamingSession 
      start 
      Nothing 
      <$> ireq (selectField (optionsPersistKey [] [] (toPathPiece . entityKey))) "player" 
      <*> ireq (selectField (optionsPersistKey [] [] (toPathPiece . entityKey))) "table" 
      <*> iopt intField "seat" 

-- | The optionsPersist builtin to the Yesod.Forms package unfortunately only 
-- works well with whole persist entities. We are only interested in the entity 
-- id s which is why we add in this function here: 
optionsPersistKey 
    :: (YesodPersist master 
    , PersistEntity a 
    , PersistQuery (YesodPersistBackend master) (GHandler sub master) 
    , PathPiece (Key (YesodPersistBackend master) a) 
    , RenderMessage master msg 
    , PersistEntityBackend a ~ YesodPersistBackend master) 
    => [Filter a] 
    -> [SelectOpt a] 
    -> (Entity a -> msg) 
    -> GHandler sub master (OptionList (Key (PersistEntityBackend a) a)) 
optionsPersistKey filts ords toDisplay = fmap mkOptionList $ do 
    mr <- getMessageRender 
    pairs <- runDB $ selectList filts ords 
    return $ map (\(Entity key value) -> Option 
     { optionDisplay = mr (toDisplay $ Entity key value) 
     , optionInternalValue = key 
     , optionExternalValue = toPathPiece key 
     }) pairs 
+0

I欣赏这一点。我建立的表单仅用于测试。最后,投入是唯一仍然存在的部分。 的值将通过javascript到底提交 – geoff 2012-03-19 16:44:34

+0

处理程序/ GamingSession.hs:51:31: 不能匹配预期类型'字符”与实际类型'实体T0' 在模式:实体密钥值 在Data.Text的第一个参数。图 '即 '(\(实体密钥值) - >选项 {optionDisplay = MR(toDisplay $实体密钥值), optionInternalValue =键,optionExternalValue = toPathPiece键})' 在'的第二个参数( $)”,即 'Data.Text.map (\(实体键值) - >选项 ... – geoff 2012-03-19 16:57:30

1

你得到的读取失败B/C你想读像“4f6150251c21230c78000000”到PersistInt64值。 MongoDB后端不会使用PersistInt64s作为键值,因此代码不会为您的设置构建适当的键。我会尝试PersistText。

+0

感谢PersistText是给我同样的错误,虽然 – geoff 2012-03-19 15:24:50

+0

请注意,从文本框的返回值将是文本,所以你不需要解压缩或读取textToKey,只需'Key。PersistText' – pbrisbin 2012-03-19 17:47:06

0

好吧,试试这个:

import Data.Text (unpack) 

... 

(player, table, seat) <- runInputPost $ (,,) 
      <$> (ireq textField "player") 
      <*> (ireq textField "table") 
      <*> iopt intField "seat" 
playerId <- maybe (invalidArgs ["couldn't parse: ", player]) return $ fromPathPiece player 
tableId <- maybe (invalidArgs ["couldn't parse: ", table]) return $ formPathPiece table 
let gs = GamingSession start Nothing playerId tableId seat 
...