2013-04-30 39 views
6

我正在尝试使用Yesod和持久性来创建网站。我对如何使用持久性API有点困惑。Haskell持久插入行(如果尚未在数据库中)

这里是我的两个表的

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不在数据库中的情况下,持久性没有足够的信息来创建新的订阅记录,因为它缺少不在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 } 
+0

尝试使用'insertBy $ Feed url'。 – 2013-04-30 10:53:19

回答

7

insertBy不采取独特的约束作为参数,getBy是比较合适的。

insertUnique 是Maybe结果的可能性很小。

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