2013-05-27 36 views
6

Nếu chúng ta đã xác định 2 đối tượng đơn giản trong file mô hình của chúng tôi, ví dụ: -Làm cách nào để xác định trường trên biểu mẫu đăng ký khóa ngoại trong Yesod?

Person 
    name Text 
    Age Int 
Book 
    title Text 
    author Text 

Chúng ta có thể xác định một hình thức applicative cho Sách như: -

addBookForm = renderDivs $ Book 
    <$> areq textField "title" Nothing 
    <*> areq textField "author" Nothing 

Tuy nhiên, nếu chúng ta muốn thay đổi tác giả từ một trường văn bản, để id của một người, như: -

Book 
    title Text 
    author PersonId 

Sau đó, các hình thức trên sẽ không biên dịch, với lỗi này: -

Couldn't match expected type `KeyBackend Database.Persist.GenericSql.Raw.SqlBackend Person' with actual type `Text' 
Expected type: Field 
       sub0 
       master0 
       (KeyBackend Database.Persist.GenericSql.Raw.SqlBackend Person) 
    Actual type: Field sub0 master0 Text 
In the first argument of `areq', namely `textField' 
In the second argument of `(<*>)', namely 
    `areq textField "author" Nothing' 

Bây giờ chúng ta xác định trường tác giả như thế nào? Chúng ta có cần sử dụng hình thức đơn thuần không?

Cảm ơn!

Trả lời

6

Thông báo lỗi có nghĩa là bạn đang cố gắng sử dụng Văn bản (từ kết quả trường) làm Khóa.

Bạn có thể sử dụng checkMMap để bọc các TextField và sửa đổi các kết quả:

addBookForm = renderDivs $ Book 
    <$> areq textField "title" Nothing 
    <*> (entityKey <$> areq authorField "author" Nothing) 
    where 
    authorField = checkMMap findAuthor (personName . entityVal) textField 

    findAuthor name = do 
    mperson <- runDB $ selectFirst [PersonName ==. name] [] 
    case mperson of 
     Just person -> return $ Right person 
     Nothing  -> return $ Left ("Person not found." :: Text) 

Chức năng findAuthor được đơn giản hơn nếu bạn thêm một constructor duy nhất cho các lĩnh vực Person:

Person 
    name Text 
    ... 
    UniquePerson name 

Sau đó, thay vì selectFirst ... bạn có thể làm

mperson <- runDB $ getBy $ UniquePerson name 
Các vấn đề liên quan