Subversion-Projekte lars-tiefland.prado

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 1
<com:TContent ID="Main">
2
 
3
<h1>Creating Active Record Classes</h1>
4
 
5
<p>
6
We need to create two <a href="http://www.pradosoft.com/demos/quickstart/?page=Database.ActiveRecord">Active Record</a> classes, <tt>UserRecord</tt> and <tt>PostRecord</tt>, to represent data records in the <tt>users</tt> and <tt>posts</tt> tables, respectively. Active Record classes must extend from the base class <tt>ActiveRecord</tt>, and must define property names that matches with the field names of the corresponding table.
7
</p>
8
 
9
<p>
10
To better organize our directories, we create a new directory <tt>protected/database</tt> to hold the class files. We also modify our application configuration by inserting the following lines. It is equivalent to adding the directory <tt>protected/database</tt> to PHP include_path, which allows us to use the classes without explicitly including them.
11
</p>
12
 
13
<com:TTextHighlighter CssClass="source" Language="xml">
14
<paths>
15
  <using namespace="Application.database.*" />
16
</paths>
17
</com:TTextHighlighter>
18
 
19
<p>
20
Instead of writing the classes manually, we will use the <a href="http://www.pradosoft.com/demos/quickstart/?page=GettingStarted.CommandLine">PRADO command line tool</a> again to generate the classes for us.
21
</p>
22
 
23
<p>
24
Under the <tt>blog</tt> directory, run the following command to enter into the interactive mode of the command line tool:
25
</p>
26
 
27
<com:TTextHighlighter CssClass="source cli" Language="text">
28
php path/to/prado-cli.php shell .
29
</com:TTextHighlighter>
30
 
31
<p>
32
We should see
33
</p>
34
 
35
<com:TTextHighlighter CssClass="source cli" Language="text">
36
Command line tools for Prado 3.1.0.
37
** Loaded PRADO appplication in directory "protected".
38
PHP-Shell - Version 0.3.1
39
(c) 2006, Jan Kneschke <jan@kneschke.de>
40
 
41
>> use '?' to open the inline help
42
 
43
>>
44
</com:TTextHighlighter>
45
 
46
<p>
47
At the prompt, enter the following two commands to create <tt>UserRecord</tt> and <tt>PostRecord</tt> classes:
48
</p>
49
 
50
<com:TTextHighlighter CssClass="source cli" Language="text">
51
>> generate users Application.database.UserRecord
52
 
53
>> generate posts Application.database.PostRecord
54
</com:TTextHighlighter>
55
 
56
<p>
57
Here we used the <a href="http://www.pradosoft.com/demos/quickstart/?page=Fundamentals.Components">namespace format</a> again to specify the classes to be created. The path <tt>Application.database.UserRecord</tt> indicates that we want the <tt>UserRecord</tt> class file to be <tt>protected/database/UserRecord.php</tt>.
58
</p>
59
 
60
<p>
61
We should see the following directory structure with two new files under <tt>protected/database</tt>:
62
</p>
63
 
64
<img src="<%~ directories2.gif %>" class="output" />
65
 
66
<p>
67
If we check the <tt>PostRecord</tt> class file, we should see the following content.
68
</p>
69
 
70
<com:TTextHighlighter CssClass="source" Language="php">
71
class PostRecord extends TActiveRecord
72
{
73
    const TABLE='posts';
74
    public $post_id;
75
    public $author_id;
76
    public $create_time;
77
    public $title;
78
    public $content;
79
    public $status;
80
 
81
    public static function finder($className=__CLASS__)
82
    {
83
        return parent::finder($className);
84
    }
85
}
86
</com:TTextHighlighter>
87
 
88
<p>
89
As we see, for each field in the <tt>posts</tt> table, the class has a corresponding data member. The constant <tt>TABLE</tt> specifies the table name for the <tt>PostRecord</tt>. The static method <tt>finder()</tt> allows us to perform query and retrieve post data in terms of <tt>PostRecord</tt> objects.
90
</p>
91
 
92
<p>
93
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 <tt>UserRecord::finder()->findAll()</tt>.
94
</p>
95
 
96
<com:TTextHighlighter CssClass="source cli" Language="text">
97
>> PostRecord::finder()->findAll()
98
array
99
(
100
    [0] => PostRecord#1
101
    (
102
        [post_id] => '1'
103
        [author_id] => 'admin'
104
        [create_time] => '1175708482'
105
        [title] => 'first post'
106
        [content] => 'this is my first post'
107
        [status] => '0'
108
        [TActiveRecord:_readOnly] => false
109
        [TActiveRecord:_connection] => null
110
        [TComponent:_e] => array()
111
    )
112
)
113
</com:TTextHighlighter>
114
 
115
<h1>Relationship Between Posts and Users</h1>
116
<p>
117
Recall that there was a foreign key relationship between the <tt>users</tt> and <tt>posts</tt> table. The entity-relationship diagram is shown below for convienence.
118
</p>
119
 
120
<img src="<%~ ER.gif %>" class="output" />
121
 
122
<p>
123
From the entity-relationship diagram above, we see that the <tt>posts</tt> table contains a field named <tt>author_id</tt>. This <tt>author_id</tt> field is a foreign key to the reference table <tt>users</tt>. In particular, the values in the  <tt>author_id</tt> field should be of that from the <tt>users</tt> table's <tt>username</tt> 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".
124
</p>
125
 
126
<p>
127
We can model the relationship between <tt>posts</tt> and <tt>users</tt> table in Active Record by modifying the <tt>PostRecord</tt> and <tt>UserRecord</tt> classes as follows.
128
</p>
129
 
130
<com:TTextHighlighter CssClass="source" Language="php">
131
class PostRecord extends TActiveRecord
132
{
133
    //... properties and methods as before
134
 
135
    public $author; //holds an UserRecord
136
 
137
    public static $RELATIONS=array
138
    (
139
        'author' => array(self::BELONGS_TO, 'UserRecord'),
140
    );
141
}
142
</com:TTextHighlighter>
143
 
144
<p>
145
The static <tt>$RELATIONS</tt> property of <tt>PostRecord</tt> defines that the property <tt>$author</tt> belongs to an <tt>UserRecord</tt>. In <tt>array(self::BELONGS_TO, 'UserRecord')</tt>, the first element defines the relationship type, in this case <tt>self::BELONGS_TO</tt>. The second element is the name of related record, in this case an <tt>UserRecord</tt>. The <tt>UserRecord</tt> is defined similarly below, the difference is that, the user record has many <tt>PostRecord</tt>s.
146
</p>
147
 
148
<com:TTextHighlighter CssClass="source" Language="php">
149
class UserRecord extends TActiveRecord
150
{
151
    //... properties and methods as before
152
 
153
    public $posts=array(); //holds an array of PostRecord
154
 
155
    public static $RELATIONS=array
156
    (
157
        'posts' => array(self::HAS_MANY, 'PostRecord'),
158
    );
159
}
160
</com:TTextHighlighter>
161
 
162
<p>
163
An array of <tt>UserRecord</tt> with and its corresponding posts may be fetched as follows.
164
</p>
165
 
166
<com:TTextHighlighter CssClass="source" Language="php">
167
$users = UserRecord::finder()->withPosts()->findAll();
168
</com:TTextHighlighter>
169
 
170
<com:TipBox>
171
The method <tt>withXXX()</tt> (where XXX is the relationship property name, in this case, <tt>Posts</tt>) fetches the corresponding <tt>PostRecords</tt> using a second query (not by using a join). The <tt>withXXX()</tt> method accepts the same arguments as other finder methods of TActiveRecord, e.g. <tt>withPosts('status = ?', 0)</tt>.
172
</com:TipBox>
173
 
174
<p>
175
Further detailed documentation can be found in the quickstart <a href="http://www.pradosoft.com/demos/quickstart/?page=Database.ActiveRecord">Active Record</a> docs.
176
</p>
177
 
178
</com:TContent>