[nycphp-talk] Cake PHP and "Active Records"

Baer, Jon jbaer at
Fri Sep 29 14:21:16 EDT 2006

Hash: SHA1

This already works in CakePHP ...

The DESCRIBE TABLE is performed and cached under /tmp/models (describing
the table structure only once)

You can also optimize your cascades by specifically telling the model
what you want from the join, ie:

$this->Model->findAll(null, array("Model.col1","OtherModel.col3"));

On your view use pr($this->_viewVars) and you will see the object

So in a nutshell, its pretty identical to RoR.

- - Jon 

- -----Original Message-----
From: talk-bounces at [mailto:talk-bounces at]
On Behalf Of Derek DeVries
Sent: Friday, September 29, 2006 12:31 PM
To: NYPHP Talk
Subject: Re: [nycphp-talk] Cake PHP and "Active Records"

   One of the interesting questions is early loading versus lazy
loading.  The Active Record from Ruby on Rails,  for instance,  lazy
loads everything and caches nothing.  When you ask for '', Ruby
immediately does something like

SELECT name from user where id=66;

Actually, in Rails the following occurs:

NoMethodError: undefined method `name' for User:Class
        from (irb):1

FYI, you can't do this. User is a class, so you need to first find an
user object whose attributes you want to get the records for.

>> user = User.find(1)

This will execute the SQL query:
SELECT * FROM users WHERE ( = 1) LIMIT 1

>> puts
=> derek

This will execute the SQL query:

BUT... Only in development mode. On production it caches this info and
no sql is executed

>> puts
=> devrieda at

now, no SQL query is executed. We've already introspected the db.

As far as eager loading sql queries, Rails has a method of doing this.
The sql for finding all comments could be written as

>> user = User.find(1, :include => :comments)

This would generate a single sql query to retrieve the user and all
associated comments so that you can now do:

>> for comment in user.comments
>>   puts comment.body
>> end

This can also cascade as much as you want and continues to only perform
one db query.

>> user = User.find(1, :include=>{:posts=>[:comments, 
>> :categorizations]})

a better explanation of how it works can be found here:

This is very possible in php, and I've written an implementation of
ActiveRecord in PHP that uses the following syntax:

>> $user = User::find(1, array('include' => array('posts' =>
array('comments', 'categorizations'))));

which can do something like this with the resulting data:
>> foreach ($user->posts as $post) {
>>     print $post->title;
>>     foreach ($post->comments as $comment) {
>>         print $comment->body;
>>     }
>>     foreach ($post->categorizations as $comment) {
>>         print $categorizations->name;
>>     }
>> }

not terribly pretty with all the array(array(array())), but it's what we
have to work with in PHP. this can get slow when there are many
associations for the active record objects, and many records are being
loaded from the db. Our own application however doesn't seem to have any
problems because we tend to use paging on any items that tend to appear
in sets greater than 250 records in the interface.
New York PHP Community Talk Mailing List

NYPHPCon 2006 Presentations Online

Show Your Participation in New York PHP
Version: GnuPG v1.4.3 (MingW32)


More information about the talk mailing list