본문 바로가기

Yii Framework/블로그 만들기

09. Post 모델의 정의

이 곳은 제가 개인적으로 YII framework의 블로그 만들기를 번역해 놓은 곳입니다.

제가 영어 전공자도.. 그렇다고 영어랑 친하지도 않습니다. 

그래서 보시면 뭔가 글도 엉성하고 말이 안맞는게 많습니다.

잘못 오역된 부분이라던지 그런 부분들 친절하게 알려주시면 바로 수정하겠습니다.

이 페지의 원글 http://www.yiiframework.com/doc/blog/1.1/en/post.model



Post 모델의 정의

Gii 도구에 의해 생성 된 Post 모델 클래스는 주로 두 가지 점에서 수정해야합니다.

  • rules () 메소드 : 모델의 속성에 대한 유효성 검사 규칙을 규정
  • relations () 메소드 : 관계형 객체를 규정

정보: 모델 은 속성 목록에서 구성됩니다. 각각의 속성은 일반적으로 해당 데이터베이스 테이블의 칼럼과 연결됩니다. 속성은 명시 적으로 클래스 멤버 변수로 선언되는 경우도 선언없이 묵시적으로 선언 될 수 있습니다.

1. rules () 메소드의 정의

먼저 데이터베이스에 저장되기 전에 사용자가 입력 한 속성 값이 올바른지 확인 유효성 검사 규칙을 지정합니다.
예를 들어, 포스트의 상태 속성은 정수 1, 2 또는 3이어야합니다Gii 도구는 각 모델에 대한 유효성 검사 규칙을 생성합니다. 그러나 이러한 규칙은 테이블 열 정보를 기반으로하고 적절하지 않을 수 있습니다.

요구 분석에 따라, rules () 메서드를 다음과 같이 수정합니다.
public function rules()
{
    return array(
        array('title, content, status', 'required'),
        array('title', 'length', 'max'=>128),
        array('status', 'in', 'range'=>array(1,2,3)),
        array('tags', 'match', 'pattern'=>'/^[\w\s,]+$/',
            'message'=>'Tags can only contain word characters.'),
        array('tags', 'normalizeTags'),
 
        array('title, status', 'safe', 'on'=>'search'),
    );
}

상기, title , content , status 속성은 필수입니다. title 의 길이는 128을 초과 할 수 없습니다. status 속성의 값은 1 (초안), 2 (공개), 3 (보관) 중 하나이어야합니다. tags 속성은 단어 문자와 쉼표 만 포함 할 수 없습니다. 또한 normalizeTags 를 사용하여 사용자가 입력 한 태그의 문자열을 정규화하고 독특한 태그 쉼표로 제대로 분리 된 문자열이되도록합니다. 마지막 규칙은 검색 기능에서 사용하지만, 이것에 대해서는 나중에 설명하겠습니다.

required , length , in , match 같은 검사기는 모든 Yii가 제공하는 기존의 것입니다. normalizeTags 검사기는 메서드 기반 검사기이며 Post 클래스에서 정의해야합니다. 유효성 검사 규칙을 정의하는 방법에 대한 자세한 정보는 가이드 를 참조하십시오.

public function normalizeTags($attribute,$params)
{
    $this->tags=Tag::array2string(array_unique(Tag::string2array($this->tags)));
}

여기서 array2string 하면 string2array 는 Tag 모델 클래스에 정의해야 새로운 방법입니다..

public static function string2array($tags)
{
    return preg_split('/\s*,\s*/',trim($tags),-1,PREG_SPLIT_NO_EMPTY);
}
 
public static function array2string($tags)
{
    return implode(', ',$tags);
}

rules () 메소드로 선언 된 규칙은 모델 인스턴스의 validate () 메소드 또는 save () 메서드를 호출 할 때 하나 하나 실행됩니다.

주의: rules()에 나타나는 속성은 최종 사용자가 입력 할 수있는 수 있다는 사실을 기억하는 것은 매우 중요합니다. Post 모델의 id 나 create_time 등 프로그램이나 데이터베이스에 의해 설정되는 속성은 rules() 에 설치할 필요가 없습니다. 자세한 내용은 보안 속성 지정을 참조하십시오.

이상 변경되면 게시물 작성 페이지를 다시 열고 새로운 검증 규칙이 작동하는 것을 확인 할 수 있습니다.


2. relations () 메소드의 정의

마지막으로  relations () 메서드를 정의하여 기사와 관련된 개체를 지정합니다. relations () 에서 관련 개체를 선언하여 관계형 액티브 레코드 (RAR) 의 강력한 기능을 이끌어 낼 수 있습니다. 즉, RAR을 사용하여 복잡한 SQL JOIN 구문을 작성하지 않고 저자 나 코멘트 등의 기사에 관련하는 오브젝트의 정보에 액세스 할 수 있습니다.

relations () 메서드를 다음과 같이 정의합니다.

public function relations()
{
    return array(
        'author' => array(self::BELONGS_TO, 'User', 'author_id'),
        'comments' => array(self::HAS_MANY, 'Comment', 'post_id',
            'condition'=>'comments.status='.Comment::STATUS_APPROVED,
            'order'=>'comments.create_time DESC'),
        'commentCount' => array(self::STAT, 'Comment', 'post_id',
            'condition'=>'status='.Comment::STATUS_APPROVED),
    );
}

동시에, 위 메소드에서 사용되는 두 상수를 Comment 모델에 추가합니다.

class Comment extends CActiveRecord
{
    const STATUS_PENDING=1;
    const STATUS_APPROVED=2;
    ......
}

relations () 에서 선언 한 관계는 다음과 같은 의미입니다.

  • 하나의 문서는 하나의 저자에 속한다. 저자의 클래스는 User 의 기사 author_id 속성에서 연결된다.
  • 하나의 기사는 많은 의견이있다. 댓글 클래스 Comment 에서 댓글 post_id 속성에서 연결된다. 코멘트 작성 날짜별로 정렬
    되어 승인 (APPROVED)의 코멘트만으로 구성된다.
  •  commentCount 는 집계 결과를 반환 조금 특별한 관계에서 기사가있는 댓글 수를 나타낸다.
위의 관계를 선언하는 것으로, 다음과 같이 간단하게 기사의 저자와 코멘트에 액세스 할 수 있습니다.
$author=$post->author;
echo $author->username;
 
$comments=$post->comments;
foreach($comments as $comment)
    echo $comment->content;

관계를 선언하고 사용하는 방법에 대한 자세한 내용은 가이드를 참조하시기 바랍니다.


3. URL 속성추가

게시물의 내용을 볼 수있는 독특한 URL이 관련된 내용입니다. 이 URL을 얻기 위해 코드 곳곳에서 CWebApplication :: createUrl 을 쓰는 것이 아니라, Post 모델에 url 속성을 추가하여 URL을 생성하는 동일한 코드를 재사용 할 수 있습니다. 나중에 URL을 아름답게하는 방법을 설명 할 때이 속성의 추가가 매우 유용한 것을 알 수 있습니다.

url 속성을 추가하기 위해 다음과 같이 Post 클래스를 수정하여 getter 메소드를 추가합니다.

class Post extends CActiveRecord
{
    public function getUrl()
    {
        return Yii::app()->createUrl('post/view', array(
            'id'=>$this->id,
            'title'=>$this->title,
        ));
    }
}

게시물 ID 외에, 우리는 또한 URL에 GET 매개 변수로 게시물 Title을 추가합니다. 이것은 우리가 URL을 미화 하는것에 대한 설명으로, 주로 검색 엔진 최적화 (SEO) 가 목적입니다.

Post 의 최상위 부모 클래스는 CComponent 이므로 getUrl () 는 getter 메소드를 추가하여 $post->url 라고 작성을 할 수있게됩니다. $post->url 에 액세스하면 getter 메소드가 실행되고, 그 결과 식의 값으로 반환합니다. 이러한 구성 요소의 기능에 대한 자세한 내용은 가이드를 를 참조하십시오.

4. 상태를 텍스트로 표현

게시물의 상태가 데이터베이스에 정수로 저장되기 때문에, 우리는 최종 사용자에게 표시되는 경우보다 직관적이 되도록 텍스트 형식의 표현을 제공해야 합니다. 대형 시스템에서 유사한 요구사항은 매우 일반적입니다.

일반적인 솔루션으로, 우리는 다른 데이터 객체로 필요한 정수 값과 텍스트 표현 사이의 매핑을 저장하기 위해 tbl_lookup테이블을 사용합니다. Lookup 모델 클래스를 다음과 같이 수정하고 테이블의 텍스트 데이터에 쉽게 액세스 할 수 있도록합니다.
class Lookup extends CActiveRecord
{
......
 
    private static $_items=array();
 
    public static function items($type)
    {
        if(!isset(self::$_items[$type]))
            self::loadItems($type);
        return self::$_items[$type];
    }
 
    public static function item($type,$code)
    {
        if(!isset(self::$_items[$type]))
            self::loadItems($type);
        return isset(self::$_items[$type][$code]) ? self::$_items[$type][$code] : false;
    }
 
    private static function loadItems($type)
    {
        self::$_items[$type]=array();
        $models=self::model()->findAll(array(
            'condition'=>'type=:type',
            'params'=>array(':type'=>$type),
            'order'=>'position',
        ));
        foreach($models as $model)
            self::$_items[$type][$model->code]=$model->name;
    }
}

새로운 코드는 주로 두 정적 메서드, Lookup :: items () 와 Lookup :: item () 를 제공합니다. 전자는 지정된 데이터 유형에 속하는 문자열의리스트를 돌려줍니다. 후자는 지정된 데이터 유형과 값에 해당하는 특정 문자열을 반환합니다.

블로그의 데이터베이스는 Lookup 유형으로 PostStatus 과 CommentStatus 가 사전에 등록되어 있습니다. 전자는 문서의 상태가 취할 수있는 값을 보여, 후자는 논평 상태가 취할 수있는 값을 보여줍니다.

또한 코드를 읽기 쉽게하기 위해 일련의 상태를 나타내는 정수 값의 상수를 선언합니다. 코드에서 각 상태 값을 참조 할 때이 상수를 사용합니다.

class Post extends CActiveRecord
{
    const STATUS_DRAFT=1;
    const STATUS_PUBLISHED=2;
    const STATUS_ARCHIVED=3;
    ......
}

따라서 Lookup::items('PostStatus') 를 호출하면 게시물의 상태가 취할 수있는 값 목록 (해당하는 정수 값을 인덱스로하는 텍스트 표현의 목록)을 얻을 수 있습니다. 또한 Lookup::item('PostStatus', Post::STATUS_PUBLISHED) 를 호출하면 공개 된라는 상태의 텍스트 표현을 얻을 수 있습니다.