【问题标题】:Haskell Persistent insert rows if not already in databaseHaskell Persistent 插入行(如果尚未在数据库中)
【发布时间】:2013-05-19 09:23:32
【问题描述】:

我正在尝试使用 Yesod 和持久性来创建一个网站。我对如何使用持久化 API 有点困惑。

这是我的两张桌子

Feed
    url Text
    UniqueFeed url

Subscription
    feed FeedId
    title Text
    UniqueSubscription feed

如果具有该 URL 的提要不存在,我将尝试创建提要,然后如果订阅尚不存在,则向该提要添加订阅。

postFeedR :: Handler RepHtml
postFeedR = do
    url <- runInputPost $ ireq urlField "url"
    title <- runInputPost $ ireq textField "title"

    runDB $ do
        feedId <- insertFeed $ UniqueFeed url
        subscriptionId <- insertSubscription feedId title
        return 

    defaultLayout [whamlet| <p>done|]

insertFeed url = do
    f <- insertBy $ UniqueFeed url
    case f of
        Left (Entity uid _) -> uid
        Right (Key uid) -> do
            (Key uid) <- insert $ Feed url
            return uid

insertSubscription feedId title = do
    s <- insertBy $ UniqueSubscription feedId
    case s of 
        Left (Entity uid _) -> uid
        Right (Key uid) -> do
            (Key uid) <- insert $ Subscription feedId title
            return uid

我收到以下错误。不明白为什么ghc认为insertFeed和insertSubscription的返回值应该是UniqueFeed和UniqueSubscription。我希望这些函数返回新创建记录的键。

另外,我好像在扔掉我在案件的每个权利条款中得到的钥匙。为什么持久返回这些键。在 UniqueSubscription 不在数据库中的情况下,persistent 没有足够的信息来创建新的订阅记录,因为它缺少标题,而该标题不在 UniqueSubscription 上。

如果有人能给我一些关于如何使用持久 API 的指导,我将不胜感激。

Handler/Home.hs:62:9:
    Kind incompatibility when matching types:
      a0 :: *
      GHandler App App :: * -> *
    Expected type: (a0 -> t0)
                   -> (t0 -> a0 -> m0 a0) -> YesodDB App App (m0 a0)
      Actual type: (a0 -> t0) -> (t0 -> a0 -> m0 a0) -> a0 -> m0 a0
    In a stmt of a 'do' block: feedId <- insertFeed $ UniqueFeed url
    In the second argument of `($)', namely
      `do { feedId <- insertFeed $ UniqueFeed url;
            subscriptionId <- insertSubscription feedId title;
            return }'

Handler/Home.hs:62:9:
    Couldn't match type `YesodPersistBackend App' with `(->)'
    Expected type: (a0 -> t0)
                   -> (t0 -> a0 -> m0 a0) -> YesodDB App App (m0 a0)
      Actual type: (a0 -> t0) -> (t0 -> a0 -> m0 a0) -> a0 -> m0 a0
    In a stmt of a 'do' block: feedId <- insertFeed $ UniqueFeed url
    In the second argument of `($)', namely
      `do { feedId <- insertFeed $ UniqueFeed url;
            subscriptionId <- insertSubscription feedId title;
            return }'

Handler/Home.hs:74:20:
    Couldn't match expected type `Unique Feed'
                with actual type `Database.Persist.Store.PersistValue'
    In the first argument of `return', namely `uid'
    In a stmt of a 'do' block: return uid
    In the expression:
      do { (Key uid) <- insert $ Feed url;
           return uid }

Handler/Home.hs:83:20:
    Couldn't match expected type `Unique Subscription'
                with actual type `Database.Persist.Store.PersistValue'
    In the first argument of `return', namely `uid'
    In a stmt of a 'do' block: return uid
    In the expression:
      do { (Key uid) <- insert $ Subscription feedId title;
           return uid }

【问题讨论】:

  • 尝试使用insertBy $ Feed url

标签: haskell yesod haskell-platform


【解决方案1】:

insertBy 不以 Unique 约束为参数,getBy 更合适。

但是 insertUnique 是可能的结果。

postFeedR :: Handler RepHtml
postFeedR = do
    url <- runInputPost $ ireq urlField "url"
    title <- runInputPost $ ireq textField "title"

    runDB $ do
        feedId <- insertFeed url
        _mbSubscriptionId <- insertUnique $ Subscription feedId title
        return ()

    defaultLayout ...

insertFeed url = do
    f <- insertBy $ Feed url
    case f of
        Left (Entity uid _) -> return uid
        Right uid -> return uid

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多