From e2cb0b52aaa02a3f3f41d0df377d189529713738 Mon Sep 17 00:00:00 2001 From: wei <> Date: Thu, 10 May 2007 23:00:04 +0000 Subject: Update blog tutorial --- .../protected/pages/Day2/CreateAR.page | 105 +++++++++++++++++---- .../protected/pages/Day2/CreateDB.page | 11 ++- demos/blog-tutorial/protected/pages/Day2/ER.gif | Bin 5172 -> 4444 bytes demos/blog-tutorial/protected/pages/Day2/ER.vsd | Bin 73216 -> 73216 bytes 4 files changed, 93 insertions(+), 23 deletions(-) (limited to 'demos/blog-tutorial/protected/pages/Day2') diff --git a/demos/blog-tutorial/protected/pages/Day2/CreateAR.page b/demos/blog-tutorial/protected/pages/Day2/CreateAR.page index 00ac1166..c8684ee0 100644 --- a/demos/blog-tutorial/protected/pages/Day2/CreateAR.page +++ b/demos/blog-tutorial/protected/pages/Day2/CreateAR.page @@ -3,7 +3,7 @@

Creating Active Record Classes

-We need to create two Active Record classes, UserRecord and PostRecord, to represent data records in the users and posts tables, respectively. Active Record classes must extend from the base class ActiveRecord, and their properties must match exactly to the fields of the corresponding tables. +We need to create two Active Record classes, UserRecord and PostRecord, to represent data records in the users and posts tables, respectively. Active Record classes must extend from the base class ActiveRecord, and must define property names that matches with the field names of the corresponding table.

@@ -11,9 +11,9 @@ To better organize our directories, we create a new directory protected/data

- - - + + +

@@ -24,7 +24,7 @@ Instead of writing the classes manually, we will use the + php path/to/prado-cli.php shell . @@ -32,7 +32,7 @@ php path/to/prado-cli.php shell . We should see

- + Command line tools for Prado 3.1.0. ** Loaded PRADO appplication in directory "protected". PHP-Shell - Version 0.3.1 @@ -47,7 +47,7 @@ PHP-Shell - Version 0.3.1 At the prompt, enter the following two commands to create UserRecord and PostRecord classes:

- + >> generate users Application.database.UserRecord >> generate posts Application.database.PostRecord @@ -70,17 +70,18 @@ If we check the PostRecord class file, we should see the following cont class PostRecord extends TActiveRecord { - const TABLE='posts'; - public $post_id; - public $author; - public $create_time; - public $title; - public $content; - - public static function finder($className=__CLASS__) - { - return parent::finder($className); - } + const TABLE='posts'; + public $post_id; + public $author_id; + public $create_time; + public $title; + public $content; + public $status; + + public static function finder($className=__CLASS__) + { + return parent::finder($className); + } } @@ -92,17 +93,18 @@ As we see, for each field in the posts table, the class has a correspon We can use the command line tool to do some testing with our newly created Active Record classes. Still in the interactive mode of the command line tool, we enter a PHP statement and should see the following. Interested readers may try some other PHP statements, such as UserRecord::finder()->findAll().

- + >> PostRecord::finder()->findAll() array ( [0] => PostRecord#1 ( [post_id] => '1' - [author] => 'admin' + [author_id] => 'admin' [create_time] => '1175708482' [title] => 'first post' [content] => 'this is my first post' + [status] => '0' [TActiveRecord:_readOnly] => false [TActiveRecord:_connection] => null [TComponent:_e] => array() @@ -110,4 +112,67 @@ array ) +

Relationship Between Posts and Users

+

+Recall that there was a foreign key relationship between the users and posts table. The entity-relationship diagram is shown below for convienence. +

+ + + +

+From the entity-relationship diagram above, we see that the posts table contains a field named author_id. This author_id field is a foreign key to the reference table users. In particular, the values in the author_id field should be of that from the users table's username field. One of the consequence of this relationship, thinking in terms of objects, is that each "post" belongs to an "author" and one "author" may have many "posts". +

+ +

+We can model the relationship between posts and users table in Active Record by modifying the PostRecord and UserRecord classes as follows. +

+ + +class PostRecord extends TActiveRecord +{ + //... properties and methods as before + + public $author; //holds an UserRecord + + protected static $RELATIONS=array + ( + 'author' => array(self::BELONGS_TO, 'UserRecord'), + ); +} + + +

+The static $RELATIONS property of PostRecord defines that the property $author belongs to an UserRecord. In array(self::BELONGS_TO, 'UserRecord'), the first element defines the relationship type, in this case self::BELONGS_TO. The second element is the name of related record, in this case an UserRecord. The UserRecord is defined similarly below, the difference is that, the user record has many PostRecords. +

+ + +class UserRecord extends TActiveRecord +{ + //... properties and methods as before + + public $posts=array(); //holds an array of PostRecord + + protected static $RELATIONS=array + ( + 'posts' => array(self::HAS_MANY, 'PostRecord'), + ); +} + + +

+An array of UserRecord with and its corresponding posts may be fetched as follows. +

+ + +$users = UserRecord::finder()->withPosts()->findAll(); + + + +The method withXXX() (where XXX is the relationship property name, in this case, Posts) fetches the corresponding PostRecords using a second query (not by using a join). The withXXX() method accepts the same arguments as other finder methods of TActiveRecord, e.g. withPosts('status = ?', 0). + + +

+Further detailed documentation can be found in the quickstart Active Record docs. +

+ \ No newline at end of file diff --git a/demos/blog-tutorial/protected/pages/Day2/CreateDB.page b/demos/blog-tutorial/protected/pages/Day2/CreateDB.page index eebda4c1..de4e2436 100644 --- a/demos/blog-tutorial/protected/pages/Day2/CreateDB.page +++ b/demos/blog-tutorial/protected/pages/Day2/CreateDB.page @@ -30,9 +30,11 @@ CREATE TABLE users ( /* create posts table */ CREATE TABLE posts ( post_id INTEGER NOT NULL PRIMARY KEY, - author VARCHAR(128) NOT NULL, /* references users.username */ + author_id VARCHAR(128) NOT NULL + CONSTRAINT fk_author REFERENCES users(username), create_time INTEGER NOT NULL, /* UNIX timestamp */ title VARCHAR(256) NOT NULL, /* title of the post */ + content TEXT, /* post body */ status INTEGER NOT NULL /* 0: published; 1: draft; 2: pending; 2: denied */ ); @@ -43,14 +45,17 @@ INSERT INTO posts VALUES (NULL, 'admin', 1175708482, 'first post', 'this is my f -SQLite does not support foreign key constraint. Therefore, we will write PHP code to ensure that the posts.author field contains valid data. Also, we are exploiting the fact that the posts.post_id field is auto-incremental if we assign NULL to it. +SQLite does not support foreign key constraint such that +the constraints can still be defined but will be ignored by SQLite. +Therefore, we will write PHP code to ensure that the posts.author_id field contains valid data. +Also, we are exploiting the fact that the posts.post_id field is auto-incremental if we assign NULL to it.

We then use the SQLite command line tool to create the SQLite database. We create a directory protected/data to hold the SQLite database file. We now execute the following command under the directory protected/data:

- + sqlite3 blog.db < ../schema.sql diff --git a/demos/blog-tutorial/protected/pages/Day2/ER.gif b/demos/blog-tutorial/protected/pages/Day2/ER.gif index 90e4c1ea..7a5397b3 100644 Binary files a/demos/blog-tutorial/protected/pages/Day2/ER.gif and b/demos/blog-tutorial/protected/pages/Day2/ER.gif differ diff --git a/demos/blog-tutorial/protected/pages/Day2/ER.vsd b/demos/blog-tutorial/protected/pages/Day2/ER.vsd index 95cf7f32..474833fd 100644 Binary files a/demos/blog-tutorial/protected/pages/Day2/ER.vsd and b/demos/blog-tutorial/protected/pages/Day2/ER.vsd differ -- cgit v1.2.3