yesodで詰まったところのメモ

yesodでちょっとエラーで詰まったことのメモ。

追記2013.7.5 Yesodのバージョンは1.1ぐらいだった気がする。

エラー1

Handler/Blog.hs:17:9:    No instance for (RenderMessage master0 FormMessage)
      arising from a use of `area'
    Possible fix:
      add an instance declaration for (RenderMessage master0 FormMessage)
    In the second argument of `(<$>)', namely
      `areq textField "Title" Nothing'
    In the first argument of `(<*>)', namely
      `Article <$> areq textField "Title" Nothing'
    In the second argument of `($)', namely
      `Article <$> areq textField "Title" Nothing
       <*> areq nicHtmlField "Content" Nothing'

Handler/Blog.hs:18:16:
    Couldn't match expected type `Text' with actual type `Html'
    Expected type: Field sub0 master0 Text
      Actual type: Field sub0 master0 Html
    In the first argument of `areq', namely `nicHtmlField'
    In the second argument of `(<*>)', namely
      `areq nicHtmlField "Content" Nothing'

areq でエラーがなぜか出る...。

modelとformの引数が違う可能性がある

config/modelsのモデルを見てみる。

-- config/models

Article
  name Text
  title Text
  content Html
  createdAt UTCTime default=CURRENT_TIMESTAMP
  deriving

見てみると、name, title, content, createdAtの4つのデータがArticleには必要だとわかる。

モデルと一致しない間違ったentryForm

-- Handler/Blog.hs
entryForm :: Form Article
entryForm = renderDivs $ Article
    <$> areq   textField "Title" Nothing
    <*> areq   nicHtmlField "Content" Nothing

これはtitleとcontentの2つしか作っていないということになる。
モデルと一致したentryForm

-- Handler/Blog.hs
entryForm :: Form Article
entryForm = renderDivs $ Article
    <$> areq   textField "Name"  Nothing
    <*> areq   textField "Title" Nothing
    <*> areq   nicHtmlField "Content" Nothing
    <*> aformM (liftIO getCurrentTime)

こっちはname, title, content, createdAtの4つに対応する形でコードが書かれているのでモデルに一致している。

http://yannesposito.com/Scratch/en/blog/Yesod-tutorial-for-newbies/
いろいろなサイトのやつを見ながらコピペで作ってたら変なエラーを起こしてしまった。できたら一つのサイトのコピペで完了させたかったのだけれど、うまく動かなかったので外のサイトのコピペで動かしてたらこんなエラーが...。

エラー2

ちゃんとgetFooRとpostFooRを書いてるのにこの2つが無いとか言われる。↓
Application.hsにHandler.Fooを入れ忘れてるかもしれない。or
HogeHoge.cabalファイルにHandler.Fooを書き忘れてるかも。
なので両方を確認して、入れてなかったらそれぞれにHandler.Fooを入れる。

Application.hsにはimportを加える。

-- Application.hs
import Data.Foo

HogeHoge.cabalには、exposed-modulesにHnadler.Fooを入れとく。

-- HogeHoge.cabal
Flag library-only
    Description:   Build for use with "yesod devel"
    Default:       False

library
    exposed-modules: Application
                     ....
                     Handelr.Foo    -- ←ここに入れる

    if flag(dev) || flag(library-only)
        cpp-options:   -DDEVELOPMENT
        ghc-options:   -Wall -O0
    else
        ghc-options:   -Wall -O2

エラー3

Handler.Mirrorを作ってる時のこと。widgetのmirrorがないとか言われる。

Exception when trying to run compile-time code:
      Called widgetFileReload on "mirror", but no template were found.
      Code: widgetFile "mirror"
    In a stmt of a 'do' block: $(widgetFile "mirror")
    In the second argument of `($)', namely
      `do { $(widgetFile "mirror") }'
    In a stmt of a 'do' block:
      defaultLayout $ do { $(widgetFile "mirror") }

widgetファイル(この場合mirror.hamlet)を定義してない。なので、templates/にmirror.hamletを作る。