2016-11-26 8 views
1

나는 Template Haskell을위한 적절한 장소라고 생각되는 흥미로운 문제를 보았습니다. yesod 및 yesod-persistant를 사용하여 웹 프론트 엔드에서 데이터베이스로 작업하고 있습니다. 내가 mkPerist 함수와 persistLowerCase 준 인용문을 사용하여 데이터베이스 유형을 생성하고 있습니다. 제 문제는 데이터베이스 필드를 편집하는 방법이 필요하지만 각각의 열에 대해 6 개의 다른 페이지에 대해 햄릿 코드를 작성하는 것은 엄청나게 반복적 인 것 같습니다. Template Haskell을 사용하여 주어진 유형의 데이터베이스 컬럼을 편집하기위한 텍스트 필드와 체크 박스를 자동으로 생성 할 수 있다고 생각했습니다. 이상적으로는 Template Haskell 함수에 형식의 이름을 전달한 다음 TH가 페이지의 Hamlet을 모두 생성하도록 처리 할 것입니다. 내 질문은,이 경우 Template Haskell을 사용할 수 있습니까? 최상의 솔루션입니까? 특히, Template Haskell이 다른 유사 쿼터 코드를 생성 할 수 있습니까? 특히 햄릿? 여기에 내 프로젝트에 대한 링크가 있습니다 : https://github.com/ProspectRidgeTech/PRADatabase 미리 감사드립니다! (추신 :이 문제에 접근하는 더 좋은 방법이 있는지, 내 질문에 대한 제안 된 수정 사항이있는 경우 알려주십시오.)템플릿 하스켈을 사용하여 햄릿 코드를 생성 할 수 있습니까?

답변

1

질문에 대답하려면 : 그렇지만 권장하지 않습니다. 준 quoter 그냥 문자열을 가지고 몇 가지 코드를 생성하는 기능입니다, 그래서 당신은 당신은 당신은

$(hamlet "blah blah") 

그래서 아무것도 TH에서 당신을 중지하지로 교체 (또는 동급) 할 수

[hamlet|blah blah|] 

를 볼 때 전화 햄릿에 문자열을 생성합니다. 그러나 TH의 요점 중 하나는 유형 안전입니다. 다음에 문자열을 생성하여 개체를 파싱합니다. 또한이 2 단계 코드 생성은 아마도 디버깅하기가 어려울 것입니다.

어쨌든 영구 엔터티에 대한 테이블을 생성하는 것이 문제라면 TH를 필요로하지 않고 영구 필드 정보 만 사용한다고 생각하지 않습니다. 비슷한 문제가있어서 엔티티 목록을위한 HTML 테이블을 생성하는 코드를 작성했습니다. 입력을 수정하는 것이 어렵지 않아야합니다. 양식을 처리하고 데이터베이스가 더 까다로울 수와 TH을해야 할 수도 있습니다 업데이트하는 코드를 작성

entitiesToTable :: PersistEntity a => (FieldDef -> Text) -> [Entity a] -> Html 
entitiesToTable getColumn entities = do 
    let eDef = entityDef (map entityVal entities) 
    [shamlet| 
<table.table.table-bordered.table-striped class="#{unHaskellName $ entityHaskell eDef}"> 
    <tr> 
    <th> Id 
    $forall field <- entityFields eDef 
     <th> #{getColumn field} 
    $forall Entity eit entity <- entities 
    <tr> 
     <td.id> #{renderPersistValue $ toPersistValue eit} 
     $forall (pfield, fieldDef) <- zip (toPersistFields entity) (entityFields eDef) 
     <td class="#{getHaskellName fieldDef}" > #{renderPersistValue $ toPersistValue pfield} 
|] 

그러나이 단계에서 반군 햄릿이 없습니다.

+0

고맙습니다! 나는이 문제의 적어도 일부를 TH없이 해결할 수 있다고 생각한다. 그것은 가장 확실한 방법이다. 나는 Persistent가 이런 종류의 정보를 제공한다는 것을 알지 못했습니다! 신속한 후속 질문으로 'getColumn'매개 변수의 출처는 어디입니까? 특정 컬럼에서 모든 엔티티리스트를 얻기 위해'(runDB $ selectList [] [])'와 같은 것을 할 수 있다고 가정하지만'(FieldDef -> Text)'는 무엇을합니까? 또한이 Persistent 함수가 정의 된 모듈에 나를 연결할 수 있습니까? 모든 도움을 주셔서 감사합니다! – thelostlambda

+0

'getColumn :: FieldDef -> Text'는 열 정의에서 이름을 추출하여 열 이름으로 사용하는 함수입니다. 나는 개인적으로'unDBName '을 사용한다. fieldDB'하지만 사례를 변경하려면 예를 들어 변경할 수 있습니다. – mb14

+0

[there] (https://hackage.haskell.org/package/persistent-2.6/docs/Database-Persist-Types.html) – mb14