 |
|
엔트리 히스토리
크리키가 이제 제법 모양을 갖추었다. 사용자 등록과 엔트리를 만들고 읽일 수 있으니 이제 실제 애플리케이션에 대해 다뤄보자.
페이지를 제대로 편집하고 볼 수 있게 되었으니 크리키 페이지를 위한 히스토리 기억 기능을 추가할 수 있다. 히스토리를 저장하는 것은 매우 간단하다. 편집한 페이지를 제출할 때 옛 페이지가 검색된다. 버전이 다르다면 옛 페이지는 히스토리 테이블에 저장되고 난 후 새로 편집한 페이지를 저장한다.
엔트리 컨트롤러 수정하기
제목 필드가 유일하지 않아도 된다는 것을 제외하고는 entry_revisions 테이블이 엔트리 테이블과 똑같다는 것을 기억할 것이다. 이는 의도적이므로 옛 엔트리를 수정된 테이블에 쉽게 넣을 수 있다.
시작하는 이들을 위해 entries_controller.php에서 var $uses = array('Entry','EntryRevision');라는 클래스 변수를 추가함으로써 Entry 컨트롤러 이상의 것이 사용된다는 것을 지정해야 한다.
주의: 만약 $uses를 정의하면 사용하고자 하는(추가적인 것뿐 아니라) 모든 모델을 포함해야 한다. 그러므로 entries_controller.php의 맨 위는 Listing 26처럼 보여야 한다.
Listing 26. entries_controller.php의 맨 위
<?php
class EntriesController extends AppController {
var $name = 'Entries';
var $helpers = array('Html', 'Form' );
var $uses = array('Entry','EntryRevision');
...
|
이렇게 하면 Entries 컨트롤러 내에서부터 EntryRevisions 컨트롤러에 접근할 수 있어 수정된 것을 쉽게 저장할 수 있다.
이제 이 상태에서 컨트롤러에 몇 줄만 더 추가하면 된다. 편집 동작에서 user_id와 ip를 업데이트하기 전에 Listing 27에 있는 줄을 추가한다.
Listing 27. 새 리비전 저장하기
$entry = $this->Entry->findByTitle($this->data['Entry']['title']);
if ($entry) {
if ($entry['Entry']['content'] == $this->data['Entry']['content']) {
$this->Session->setFlash('No changes were made.');
$this->redirect('/entries/view/'.$this->data['Entry']['title']);
exit;
} else {
$revision['EntryRevision'] = $entry['Entry'];
unset($revision['EntryRevision']['id']);
$this->EntryRevision->save($revision);
}
$this->data['Entry']['revision'] = $entry['Entry']['revision']+1;
}
|
쉽게 설명하자면 "기존 엔트리를 가져온다. 만약 내용이 수정되지 않았다면 아무것도 할 필요 없다. 수정되었다면 ID를 덤프하고 EntryRevision 컨트롤러와 함께 데이터를 저장하고 개정 번호를 늘린다" 정도가 되겠다.
이게 전부다. 엔트리를 편집해 보고 http://localhost/entry_revisions를 방문하여 개정 목록을 보자. 엔트리의 옛 버전을 개정 목록에서 볼 수 있을 것이다.
EntryRevision 모델 업데이트하기
Entry 모델의 경우처럼 엔트리와 연관된 사용자 데이터를 엔트리로 찾아올 수 있게 EntryRevision 모델이 사용자와 관계가 있음을 지정할 필요가 있다. 이 연관은 Entry 모델에서와 똑같은 모습일 것이다.
Listing 28. 사용자와 EntryRevision 모델의 관계 지정하기
var $belongsTo = array('User' => array (
'className' => 'User',
'conditions' => ,
'order' => ,
'foreignKey' => 'user_id'
)
);
|
이제 모델을 다룰 수 있으니 컨트롤러를 업데이트해야 한다.
EntryRevisions 컨트롤러 업데이트하기
EntryRevision 컨트롤러는 두 가지 목적을 위해서만 존재한다. 첫 번째 목적은 특정 엔트리를 위한 개정 목록을 보여주기 위함이다. 이는 인덱스 동작을 수정하면 된다. 두 번째 목적은 개별 개정을 보여주는 것이다. 이는 뷰 동작이 될 것이다. 추가, 편집, 삭제 동작은 지워져야 한다.
수정 목록 보여주기
인덱스 동작을 살펴보자.
Listing 29. 인덱스 동작
function index() {
$this->EntryRevision->recursive = 0;
$this->set('entryRevisions', $this->EntryRevision->findAll());
}
|
수정을 약간만 하면 특정 제목에 대한 모든 개정 내역을 가져오는 데 사용할 수 있다.
Listing 30. 특정 제목에 대한 모든 개정 내역 가져오기
function index($title = null) {
$this->EntryRevision->recursive = 0;
if ($title) {
$revisions = $this->EntryRevision->findAllByTitle($title);
if ($revisions) {
$this->set('entryRevisions', $revisions);
} else {
$this->Session->setFlash('No Revision History For This Article');
$this->redirect('/entries/view/' . $title);
}
} else {
$this->set('entryRevisions', $this->EntryRevision->findAll());
}
}
|
이제 http://localhost/entry_revisions/index/TITLE를 방문하면 제목에 대한 개개 엔트리에 대한 개정 히스토리를 볼 수 있다. 일단 뷰를 업데이트했다면 말이다.
EntryRevisions 뷰 업데이트하기
EntryRevisions을 위한 뷰와 인덱스 뷰를 다시 편집하기보다는 간단하게 app/views/entries/에서 /app/views/entry_revisions로 복사만 하면 된다. 옮기는 것이 아니라 복사 말이다. 이 뷰는 EntryRevision 뷰의 템플릿 같은 역할을 할 것이다. 또한 app/views/entries와 app/views/entry_revisions에서 추가와 삭제 뷰를 지워야 한다. 필요 없기 때문이다.
뷰와 인덱스 뷰에 대해 다음을 변경해야 한다.
- 편집 링크를 제거한다 - 개정 내역을 편집하는 일은 없을 것이다.
-
['Entry'] 인스턴스를 ['EntryRevision']로 변경한다.
-
entries' 인스턴스를 'entryRevisions로 변경한다.
- ID에 의한 뷰를 가져오기 위해 개정에 대한 뷰 링크를 변경한다. - 수정 히스토리에서 제목은 유일하지 않다는 것을 기억하자.
- 뷰의 뷰를 변경하여 수정 횟수를 보여준다.
기본적인 이해를 하게 되었다. 변경사항이 명확하지 않으면 소스 코드를 참조한다.
새 뷰를 갖게 되었다. 시간을 들여 개정을 만들고 이것이 어떻게 흐르는지 살펴본다.
|