自定义日志模型

yiic 工具生成的 Post 日志模型类主要需要做如下两处修改:

信息: 模型 包含了一系列属性,每个属性关联到数据表中相应的列。属性可以在类成员变量中显式定义,也可以隐式定义,不需要事先声明。

自定义 rules() 方法

我们先来指定验证规则,它可以确保用户输入的信息在保存到数据库之前是正确的。例如, Poststatus 属性应该是 1, 2 或 3 中的任一数字。 yiic 工具其实也为每个模型生成了验证规则,但是这些规则是基于数据表的列信息的,可能并不是非常恰当。

基于需求分析,我们把 rules() 做如下修改:



在上面的代码中,我们指定了 title, contentstatus 属性是必填项;title 的长度不能超过 128;status 属性值应该是 1 (草稿), 2 (已发布) 或 3 (已存档);tags 属性应只允许使用单词字母和逗号。另外,我们使用 normalizeTags 来规范化用户输入的Tag,使Tag是唯一的且整齐地通过逗号分隔。最后的规则会被搜索功能用到,这个我们后面再讲。

required, length, inmatch 这几个验证器(validator)是Yii提供的内置验证器。normalizeTags 验证器是一个基于方法的验证器,我们需要在 Post 类中定义它。关于如何设置验证规则的更多信息,请参考 指南



其中的 array2stringstring2array 是在 Tag 模型类中定义的新方法。详情请参考 /wwwroot/yii/demos/blog/protected/models/Tag.php 文件。

rules() 方法中定义的规则会在模型实例调用其 validate()save() 方法时逐一执行。

注意: 请务必记住 rules() 中出现的属性必须是那些通过用户输入的属性。其他的属性,如 Post 模型中的 idcreate_time ,是通过我们的代码或数据库设定的,不应该出现在 rules() 中。详情请参考 属性的安全赋值(Securing Attribute Assignments).

作出这些修改之后,我们可以再次访问日志创建页检查新的验证规则是否已生效。

自定义 relations() 方法

最后我们来自定义 relations() 方法,以指定与日志相关的对象。通过在 relations() 中声明这些相关对象,我们就可以利用强大的 Relational ActiveRecord (RAR) 功能来访问日志的相关对象,例如它的作者和评论。不需要自己写复杂的 SQL JOIN 语句。

我们自定义 relations() 方法如下:



我们还在 Comment 模型类中定义了两个在上面的方法中用到的常量。



relations() 中声明的关系表明:

通过以上的关系声明,我们现在可以按下面的方式很容易的访问日志的作者和评论信息。



关于如何声明和使用关系的更多详情,请参考 指南.

添加 url 属性

日志是一份可以通过一个唯一的URL访问的内容。我们可以在 Post 模型中添加一个 url 属性,这样同样的创建URL的代码就可以被复用,而不是在代码中到处调用 CWebApplication::createUrl 。 稍后讲解怎样美化 URL 的时候,我们将看到添加这个属性给我们带来了超拽的便利。

要添加 url 属性,我们可以按如下方式给 Post 类添加一个 getter 方法:



注意我们除了使用日志的ID之外,还添加了日志的标题作为URL中的一个 GET 参数。这主要是为了搜索引擎优化 (SEO) 的目的,在 美化 URL 中将会讲述。

由于 CComponentPost 的最顶级父类,添加 getUrl() 这个 getter 方法使我们可以使用类似 $post->url 这样的表达式。当我们访问 $post->url 时,getter 方法将会被执行,它的返回结果会成为此表达式的值。关于这种组件的更多详情,请参考 指南

以文本方式显示状态

由于日志的状态在数据库中是以一个整型数字存储的,我们需要提供一个文本话的表现形式,这样在它显示给最终用户时会更加直观。在一个大的系统中,类似的需求是很常见的。

作为一个总体的解决方案,我们使用 tbl_lookup 表存储数字值和被用于其他数据对象的文本值的映射。为了更简单的访问表中的文本数据,我们按如下方式修改 Lookup 模型类:



我们的新代码主要提供了两个静态方法: Lookup::items()Lookup::item()。前者返回一个属于指定的数据类型的字符串列表,后者按指定的数据类型和数据值返回一个具体的字符串。

我们的博客数据库已经预置了两个查询类别: PostStatusCommentStatus。前者代表可用的日志状态,后者代表评论状态。

为了使我们的代码更加易读,我们还定义了一系列常量,用于表示整数型状态值。我们应该在涉及到相应的状态值时在代码中使用这些常量。



这样,我们可以通过调用 Lookup::items('PostStatus') 来获取可用的日志状态列表(按相应的整数值索引的文本字符串),通过调用 Lookup::item('PostStatus', Post::STATUS_PUBLISHED) 来获取发布状态的文本表现形式。

$Id: post.model.txt 2119 2010-05-10 01:27:29Z qiang.xue $