2011-08-19 2 views
3

먼저 sfFormPropel 양식의 인터페이스가 일치하지 않는다고 가정 해 보겠습니다. bind()은 아무 것도 반환하지 않지만 유효성 검사를 실행하면 저장된 객체를 반환하는 save()과 실제로 isValid()의 반환 값인 부울을 반환하는 bindAndSave()이 반환됩니다. 이제는 작동하는 응용 프로그램이 있지만 코드가 옳다고 생각하지 않으며 symfony에 익숙합니다. 그래서 아마도 누락되었습니다.추가 속성이있는 객체를 저장하는 symfony/propel 양식

생성해야하는 개체에는 양식에 표시되지 않고 모델 외부에 있으며 응용 프로그램에서 처리합니다 (예 : 사용자의 사용자 ID, 개체를 만든 사용자 ID, 외부에서 생성 된 GUID 등).

오른쪽 지금 흐름은 다음과 같다 :

  • 양식이 유효하다면
  • , 추가 값을 추가하고 형성하도록 결합 유효한 경우
  • 검사를 형성하기 위해 요청에서 값을 얻을하고 바인딩 한 번 더
  • 가 양식을 저장하고 객체

에게 확실한 대답을 돌려 응용 프로그램 별 추가 할 것 값을 요청에서 검색하지만 값은 양식이 유효하지 않은 경우 응용 프로그램 고유 값을 바인드하는 것이 비효율적 일 수 있으며 데이터베이스 레코드를 생성 할 수 있기 때문에 바인드하는 것이 바람직하지 않습니다. 또한, 게시물 요청과 함께 해당 값을 전달할 수 없으면 응용 프로그램에서만 제공해야합니다.

이제는 모델에서 이러한 작업을 수행해야하지만 데이터가 모델 외부에 있으므로 작업을 모델에 전달해야합니다. 문제는 (bind()) 이후에 전화하면 이전 데이터가 남아 있고 제출 된 데이터가 남아 있지 않다는 것입니다.

이러한 종류의 후 처리를 구현하는 올바른 방법은 무엇입니까?

둘째 현상금 수상 다른 가치있는 대답

답변

1

개인의 종류는 추가 속성에 대해 "지식"이있는 사람에 따라 다릅니다. 그들이 정말로 특정 요청을 컨트롤러에서 처리해야 할 경우, 바인딩을 위해 유효한지 테스트 한 다음 바인딩 된 개체를 업데이트합니다. 바인딩 된 (유효성 검사 된) 필드가있는 업데이트 된 객체를 가져 오려면 updateObject 함수를 사용하십시오.

$form->bind(..) 
if ($form->isValid()) { 

    $obj = $form->updateObject(); // Updates the values of the object with the cleaned up values. (returns object) 
    $obj->foo = 'bar'; 

    $obj->save(); 
} 

그러나 일반적으로 양식 특정 동작이기 때문에 일반적으로 Form 클래스를 재정의합니다. doUpdateValues() 함수를 재정 의하여 제출 된 데이터에 쉽게 액세스하고 자신의 데이터를 추가 할 수 있습니다. 물론 체인에서 더 높이 올라갈 수 있으며 save() 함수를 재정의 할 수 있습니다. 이 양식에 대한 사용자 정의 데이터를 설정하기 위해 공개 메소드를 '게시'할 수 있으며이 메소드는 컨트롤러에서 사용할 수 있습니다.

+0

컨트롤러에는 지식이 있습니다. 값 중 하나가 현재 사용자 ID (양식에 쉽게 설정 될 수 있음)이고, 다른 ID는 다른 모델에 대한 호출로 생성되고 검색된 ID입니다. 호출은 제출 된 양식이 유효하지 않음), 다른 모델에서 검색 한 다른 값을 추후에 추가 할 수 있습니다. 질문은 실제로 처리 된 필드에서 유효성 검사를 트리거하지 않고 바운드 개체를 업데이트하는 방법입니다. –

+0

'바인딩 된'객체를 가져 오기 위해'doUpdateObject()'를 호출 해 보았습니까? (내 업데이트 된 답변 참조) –

+0

그것은 작동하며 코드는 훨씬 깨끗합니다. 고맙습니다. processValues ​​()는 다른 상황에서 유용 할 것입니다. 나는 금요일까지 질문과 현상금을 열어두고, 다른 제안을 환영한다. –

2

올바른 방법은 양식 생성자에 전달하는 개체의 기본 값을 설정하는 것으로 시작됩니다. 예를 들어, 당신은 당신이 만드는 개체에 대한 사용자 ID 로그인을 설정하려면 :

$article = new Article(); 
$article->setUserId($this->getUser()->getId()); 
$form = new ArticleForm($article); 
if ($request->isMethod('post')) { 
    $form->bind($request->getParameter('article')); 
    if ($form->isValid()) { 
    $form->save(); 
    } 
} 

은 마찬가지로 개체를 기존의, 당신은 기록을로드 할 수 있습니다 양식 생성자에 전달하기 전에 모든 속성을 변경합니다.

편집 : 당신의 유효성을 검사 한 후 개체를 수정하려는 경우, 당신은 $ 형상 -를 사용할 수 있습니다

> updateObject는() 대학원 그의 응답 제안처럼.생성 된 값이 제출 한 값에 의존하는 경우 sfFormObject :: processValues ​​() 재정의 할 수 있습니다 : 당신이 행동에서 뭔가를해야 할 경우

class UserForm { 

    public function processValues($values) { 
    $values['hash'] = sha1($values['id'] . $values['username']); 
    return parent::processValues($values); 
    } 

} 

을, 당신은 항상 폼에 옵션으로 전달할 수 :

$form = new UserForm($user, array('foo' => $bar)); 

그런 식으로, 당신은 당신의 폼 코드 어디서나 $ this-> getOption ('foo')를 사용할 수 있습니다. in processValues ​​().

+0

토론에 참여해 주셔서 감사합니다. 그래도 개체를 저장하기 전에 GUID를 생성해야하며 개체를 저장하지 못할 수도 있습니다. 값이 양식의 제출 된 데이터에 따라 달라지는 경우 (예 : 태그를 입력하는 경우), 해시가 입력 된 모든 단어 (예를 들어)를 기반으로 생성되는 경우 어떻게할까요? 어쩌면 어떤 일이 생기면 모델을 변경해야합니다. ubdateObject()는 PropelForm에서 무엇을합니까? 어쩌면 양식의 doSave()를 덮어 써야합니까? –

+0

내 답변을 편집했습니다. – Gerry

관련 문제